📌  相关文章
📜  交换循环链表中的第一个和最后一个节点

📅  最后修改于: 2022-05-13 01:57:44.279000             🧑  作者: Mango

交换循环链表中的第一个和最后一个节点

给定循环链表交换第一个和最后一个节点。任务应该只用一个额外的节点来完成,你不能声明一个以上的额外节点,也不允许你声明任何其他临时变量。
注意:额外的节点意味着需要一个节点来遍历一个列表。

https://media.geeksforgeeks.org/wp-content/uploads/Capturehgh.png

例子:

Input : 5 4 3 2 1
Output : 1 4 3 2 5

Input  : 6 1 2 3 4 5 6 7 8 9
Output : 9 1 2 3 4 5 6 7 8 6

方法一:(通过改变第一个和最后一个节点的链接)
我们首先找到一个指向最后一个节点的前一个节点的指针。令该节点为 p。现在我们更改下一个链接,以便交换最后一个和第一个节点。

C++
// CPP program to exchange first and
// last node in circular linked list
#include 
using namespace std;
  
struct Node {
    int data;
    struct Node* next;
};
  
struct Node* addToEmpty(struct Node* head, int data)
{
    // This function is only for empty list
    if (head != NULL)
        return head;
  
    // Creating a node dynamically.
    struct Node* temp
        = (struct Node*)malloc(sizeof(struct Node));
  
    // Assigning the data.
    temp->data = data;
    head = temp;
  
    // Creating the link.
    head->next = head;
  
    return head;
}
  
struct Node* addBegin(struct Node* head, int data)
{
    if (head == NULL)
        return addToEmpty(head, data);
  
    struct Node* temp
        = (struct Node*)malloc(sizeof(struct Node));
  
    temp->data = data;
    temp->next = head->next;
    head->next = temp;
  
    return head;
}
  
/* function for traversing the list */
void traverse(struct Node* head)
{
    struct Node* p;
  
    // If list is empty, return.
    if (head == NULL) {
        cout << "List is empty." << endl;
        return;
    }
  
    // Pointing to first Node of the list.
    p = head;
  
    // Traversing the list.
    do {
        cout << p->data << " ";
        p = p->next;
  
    } while (p != head);
}
  
/* Function to exchange first and last node*/
struct Node* exchangeNodes(struct Node* head)
{
    // If list is of length 2
    if (head->next->next == head) {
        head = head->next;
        return head;
    }
  
    // Find pointer to previous of last node
    struct Node* p = head;
    while (p->next->next != head)
        p = p->next;
  
    /* Exchange first and last nodes using
       head and p */
    p->next->next = head->next;
    head->next = p->next;
    p->next = head;
    head = head->next;
  
    return head;
}
  
// Driven Program
int main()
{
    int i;
    struct Node* head = NULL;
    head = addToEmpty(head, 6);
  
    for (i = 5; i > 0; i--)
        head = addBegin(head, i);
    cout << "List Before: ";
    traverse(head);
    cout << endl;
  
    cout << "List After: ";
    head = exchangeNodes(head);
    traverse(head);
  
    return 0;
}


Java
// Java program to exchange
// first and last node in
// circular linked list
class GFG {
  
    static class Node {
        int data;
        Node next;
    };
  
    static Node addToEmpty(Node head, int data)
    {
        // This function is only
        // for empty list
        if (head != null)
            return head;
  
        // Creating a node dynamically.
        Node temp = new Node();
  
        // Assigning the data.
        temp.data = data;
        head = temp;
  
        // Creating the link.
        head.next = head;
  
        return head;
    }
  
    static Node addBegin(Node head, int data)
    {
        if (head == null)
            return addToEmpty(head, data);
  
        Node temp = new Node();
  
        temp.data = data;
        temp.next = head.next;
        head.next = temp;
  
        return head;
    }
  
    // function for traversing the list
    static void traverse(Node head)
    {
        Node p;
  
        // If list is empty, return.
        if (head == null) {
            System.out.print("List is empty.");
            return;
        }
  
        // Pointing to first
        // Node of the list.
        p = head;
  
        // Traversing the list.
        do {
            System.out.print(p.data + " ");
            p = p.next;
  
        } while (p != head);
    }
  
    // Function to exchange
    // first and last node
    static Node exchangeNodes(Node head)
    {
  
        // If list is of length 2
        if (head.next.next == head) {
            head = head.next;
            return head;
        }
        // Find pointer to previous
        // of last node
        Node p = head;
        while (p.next.next != head)
            p = p.next;
  
        // Exchange first and last
        // nodes using head and p
        p.next.next = head.next;
        head.next = p.next;
        p.next = head;
        head = head.next;
  
        return head;
    }
  
    // Driver Code
    public static void main(String args[])
    {
        int i;
        Node head = null;
        head = addToEmpty(head, 6);
  
        for (i = 5; i > 0; i--)
            head = addBegin(head, i);
        System.out.print("List Before: ");
        traverse(head);
        System.out.println();
  
        System.out.print("List After: ");
        head = exchangeNodes(head);
        traverse(head);
    }
}
  
// This code is contributed
// by Arnab Kundu


Python3
# Python3 program to exchange first and
# last node in circular linked list
import math
  
  
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
  
  
def addToEmpty(head, data):
  
    # This function is only for empty list
    if (head != None):
        return head
  
    # Creating a node dynamically.
    temp = Node(data)
  
    # Assigning the data.
    temp.data = data
    head = temp
  
    # Creating the link.
    head.next = head
    return head
  
  
def addBegin(head, data):
  
    if (head == None):
        return addToEmpty(head, data)
  
    temp = Node(data)
    temp.data = data
    temp.next = head.next
    head.next = temp
  
    return head
  
# function for traversing the list
  
  
def traverse(head):
  
    # If list is empty, return.
    if (head == None):
  
        print("List is empty.")
        return
  
    # Pointing to first Node of the list.
    p = head
    print(p.data, end=" ")
    p = p.next
  
    # Traversing the list.
    while(p != head):
  
        print(p.data, end=" ")
        p = p.next
  
  
def exchangeNodes(head):
  
    # Cases Handled: Linked List either empty or containing single node.
    if head == None or head.next == head:
        return head
    # Cases Handled: Linked List containing only two nodes
    elif head.next.next == head:
        head = head.next
        return head
    # Cases Handled: Linked List containing multiple nodes
    else:
        prev = None
        curr = head
        temp = head
        # finding last and second last nodes in linkedlist list
        while curr.next != head:
            prev = curr
            curr = curr.next
  
        # point the last node to second node of the list
        curr.next = temp.next
        # point the second last node to first node
        prev.next = temp
        # point the end of node to start ( make linked list circular )
        temp.next = curr
        # mark the starting of linked list
        head = curr
  
        return head
  
  
# Driver Code
if __name__ == '__main__':
  
    head = None
    head = addToEmpty(head, 6)
    for x in range(5, 0, -1):
        head = addBegin(head, x)
    print("List Before: ", end="")
    traverse(head)
    print()
  
    print("List After: ", end="")
    head = exchangeNodes(head)
    traverse(head)
  
# This code is contributed by Srathore
# Improved by Vinay Kumar (vinaykumar71)


C#
// C# program to exchange
// first and last node in
// circular linked list
using System;
  
public class GFG {
  
    class Node {
        public int data;
        public Node next;
    };
  
    static Node addToEmpty(Node head, int data)
    {
        // This function is only
        // for empty list
        if (head != null)
            return head;
  
        // Creating a node dynamically.
        Node temp = new Node();
  
        // Assigning the data.
        temp.data = data;
        head = temp;
  
        // Creating the link.
        head.next = head;
  
        return head;
    }
  
    static Node addBegin(Node head, int data)
    {
        if (head == null)
            return addToEmpty(head, data);
  
        Node temp = new Node();
  
        temp.data = data;
        temp.next = head.next;
        head.next = temp;
  
        return head;
    }
  
    // function for traversing the list
    static void traverse(Node head)
    {
        Node p;
  
        // If list is empty, return.
        if (head == null) {
            Console.Write("List is empty.");
            return;
        }
  
        // Pointing to first
        // Node of the list.
        p = head;
  
        // Traversing the list.
        do {
            Console.Write(p.data + " ");
            p = p.next;
  
        } while (p != head);
    }
  
    // Function to exchange
    // first and last node
    static Node exchangeNodes(Node head)
    {
  
        // If list is of length 2
        if (head.next.next == head) {
            head = head.next;
            return head;
        }
        // Find pointer to previous
        // of last node
        Node p = head;
        while (p.next.next != head)
            p = p.next;
  
        // Exchange first and last
        // nodes using head and p
        p.next.next = head.next;
        head.next = p.next;
        p.next = head;
        head = head.next;
  
        return head;
    }
  
    // Driver Code
    public static void Main()
    {
        int i;
        Node head = null;
        head = addToEmpty(head, 6);
  
        for (i = 5; i > 0; i--)
            head = addBegin(head, i);
        Console.Write("List Before: ");
        traverse(head);
        Console.WriteLine();
  
        Console.Write("List After: ");
        head = exchangeNodes(head);
        traverse(head);
    }
}
  
/* This code is contributed PrinciRaj1992 */


Javascript


C++
// CPP program to exchange first and
// last node in circular linked list
#include 
using namespace std;
  
struct Node {
    int data;
    struct Node* next;
};
  
struct Node* addToEmpty(struct Node* head, int data)
{
    // This function is only for empty list
    if (head != NULL)
        return head;
  
    // Creating a node dynamically.
    struct Node* temp
        = (struct Node*)malloc(sizeof(struct Node));
  
    // Assigning the data.
    temp->data = data;
    head = temp;
  
    // Creating the link.
    head->next = head;
  
    return head;
}
  
struct Node* addBegin(struct Node* head, int data)
{
    if (head == NULL)
        return addToEmpty(head, data);
  
    struct Node* temp
        = (struct Node*)malloc(sizeof(struct Node));
  
    temp->data = data;
    temp->next = head->next;
    head->next = temp;
  
    return head;
}
  
/* function for traversing the list */
void traverse(struct Node* head)
{
    struct Node* p;
  
    // If list is empty, return.
    if (head == NULL) {
        cout << "List is empty." << endl;
        return;
    }
  
    // Pointing to first Node of the list.
    p = head;
  
    // Traversing the list.
    do {
        cout << p->data << " ";
        p = p->next;
  
    } while (p != head);
}
  
/* Function to exchange first and last node*/
struct Node* exchangeNodes(struct Node* head)
{
      
    // If list is of length less than 2
    if (head == NULL || head->next == NULL) {
        return head;
    }
    Node* tail = head;
    
    // Find pointer to the last node
    while (tail->next != head) {
        tail = tail->next;
    }
    /* Exchange first and last nodes using
       head and p */
    
    // temporary variable to store
    // head data
    int temp = tail->data; 
    tail->data = head->data;
    head->data = temp;
    return head;
}
  
// Driven Program
int main()
{
    int i;
    struct Node* head = NULL;
    head = addToEmpty(head, 6);
  
    for (i = 5; i > 0; i--)
        head = addBegin(head, i);
    cout << "List Before: ";
    traverse(head);
    cout << endl;
  
    cout << "List After: ";
    head = exchangeNodes(head);
    traverse(head);
  
    return 0;
}


输出

List Before: 6 1 2 3 4 5 
List After: 5 1 2 3 4 6 

方法2:(通过交换第一个和最后一个节点的值)

算法:

  1. 遍历列表并找到最后一个节点(尾部)。
  2. 交换头部和尾部的数据。

下面是算法的实现:

C++

// CPP program to exchange first and
// last node in circular linked list
#include 
using namespace std;
  
struct Node {
    int data;
    struct Node* next;
};
  
struct Node* addToEmpty(struct Node* head, int data)
{
    // This function is only for empty list
    if (head != NULL)
        return head;
  
    // Creating a node dynamically.
    struct Node* temp
        = (struct Node*)malloc(sizeof(struct Node));
  
    // Assigning the data.
    temp->data = data;
    head = temp;
  
    // Creating the link.
    head->next = head;
  
    return head;
}
  
struct Node* addBegin(struct Node* head, int data)
{
    if (head == NULL)
        return addToEmpty(head, data);
  
    struct Node* temp
        = (struct Node*)malloc(sizeof(struct Node));
  
    temp->data = data;
    temp->next = head->next;
    head->next = temp;
  
    return head;
}
  
/* function for traversing the list */
void traverse(struct Node* head)
{
    struct Node* p;
  
    // If list is empty, return.
    if (head == NULL) {
        cout << "List is empty." << endl;
        return;
    }
  
    // Pointing to first Node of the list.
    p = head;
  
    // Traversing the list.
    do {
        cout << p->data << " ";
        p = p->next;
  
    } while (p != head);
}
  
/* Function to exchange first and last node*/
struct Node* exchangeNodes(struct Node* head)
{
      
    // If list is of length less than 2
    if (head == NULL || head->next == NULL) {
        return head;
    }
    Node* tail = head;
    
    // Find pointer to the last node
    while (tail->next != head) {
        tail = tail->next;
    }
    /* Exchange first and last nodes using
       head and p */
    
    // temporary variable to store
    // head data
    int temp = tail->data; 
    tail->data = head->data;
    head->data = temp;
    return head;
}
  
// Driven Program
int main()
{
    int i;
    struct Node* head = NULL;
    head = addToEmpty(head, 6);
  
    for (i = 5; i > 0; i--)
        head = addBegin(head, i);
    cout << "List Before: ";
    traverse(head);
    cout << endl;
  
    cout << "List After: ";
    head = exchangeNodes(head);
    traverse(head);
  
    return 0;
}
输出
List Before: 6 1 2 3 4 5 
List After: 5 1 2 3 4 6 

时间复杂度: O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程