📜  反向双向链表 |设置 4(交换数据)

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

反向双向链表 |设置 4(交换数据)

给定一个双向链表,我们被要求在不使用任何额外空间的情况下原地反转列表。

例子:

Input : 1 <--> 2 <--> 5 <--> 6 <--> 7
Output : 7 <--> 6 <--> 5 <--> 2 <--> 1

Input : 11 <--> 22 <--> 33 <--> 22 <--> 1
Output : 1 <--> 22 <--> 33 <--> 22 <--> 11 

我们已经讨论了三种反转双向链表的方法:反转双向链表、反转双向链表(第 2 组)和使用递归反转双向链表。
前两种方法在 O(n) 时间内工作并且不需要额外的空间。第一种方法通过交换每个节点的下一个和上一个指针来工作。第二种方法从列表中取出每个节点并将其添加到列表的开头。
还有另一种方法更直观,但成本也更高。
这种方法类似于反向数组。为了反转数组,我们放置了两个指针——一个在列表的开头,另一个在列表的末尾。然后我们交换两个指针的数据并使两个指针相互靠近。当两个指针相遇或相互交叉时,我们停止。我们正好执行 n/2 次交换,时间复杂度也是 O(N)。
双向链表同时具有前一个指针和下一个指针,这意味着我们可以在列表中向前和向后两个方向遍历。因此,如果我们将一个指针(比如左指针)放在列表的开头,将另一个右指针放在列表的末尾,我们可以通过前进左指针和后退右指针来将这些指针移向彼此。

算法

Step 1: Set LEFT to head of list
Step 2: Traverse the list and set RIGHT to end of the list 
Step 3: Repeat following steps while LEFT != RIGHT and 
        LEFT->PREV != RIGHT
Step 4: Swap LEFT->DATA and RIGHT->DATA
Step 5: Advance LEFT pointer by one, LEFT = LEFT->NEXT
Step 6: Recede RIGHT pointer by one, i.e RIGHT = RIGHT->PREV
        [END OF LOOP]
Step 7: End

关于三种方法的比较效率的说明
必须提到一些事情。这种方法实现起来很简单,但与指针交换方法相比,它的成本也更高。这是因为我们交换数据而不是指针。如果节点是具有多个数据成员的大型复杂数据类型,则交换数据的成本可能更高。相比之下,指向节点的指针将始终是更简单的数据类型,并且是 4 或 8 个字节。



下面是算法的实现。

C++
// Cpp Program to Reverse a List using Data Swapping
 
#include 
using namespace std;
 
struct Node {
    int data;
    struct Node *prev, *next;
};
 
Node* newNode(int val)
{
    Node* temp = new Node;
    temp->data = val;
    temp->prev = temp->next = nullptr;
    return temp;
}
 
void printList(Node* head)
{
    while (head->next != nullptr) {
        cout << head->data << " <--> ";
        head = head->next;
    }
    cout << head->data << endl;
}
 
// Insert a new node at the head of the list
void insert(Node** head, int val)
{
    Node* temp = newNode(val);
    temp->next = *head;
    (*head)->prev = temp;
    (*head) = temp;
}
 
// Function to reverse the list
void reverseList(Node** head)
{
    Node* left = *head, * right = *head;
 
    // Traverse the list and set right pointer to
    // end of list
    while (right->next != nullptr)
        right = right->next;
 
    // Swap data of left and right pointer and move
    // them towards each other until they meet or
    // cross each other
    while (left != right && left->prev != right) {
 
        // Swap data of left and right pointer
        swap(left->data, right->data);
 
        // Advance left pointer
        left = left->next;
 
        // Advance right pointer
        right = right->prev;
    }
}
 
// Driver code
int main()
{
    Node* head = newNode(5);
    insert(&head, 4);
    insert(&head, 3);
    insert(&head, 2);
    insert(&head, 1);
 
    printList(head);
    cout << "List After Reversing" << endl;
    reverseList(&head);
    printList(head);
 
    return 0;
}


Java
// Java Program to Reverse a List using Data Swapping
class GFG
{
static class Node
{
    int data;
    Node prev, next;
};
 
static Node newNode(int val)
{
    Node temp = new Node();
    temp.data = val;
    temp.prev = temp.next = null;
    return temp;
}
 
static void printList(Node head)
{
    while (head.next != null)
    {
        System.out.print(head.data+ " <-> ");
        head = head.next;
    }
    System.out.println( head.data );
}
 
// Insert a new node at the head of the list
static Node insert(Node head, int val)
{
    Node temp = newNode(val);
    temp.next = head;
    (head).prev = temp;
    (head) = temp;
    return head;
}
 
// Function to reverse the list
static Node reverseList(Node head)
{
    Node left = head, right = head;
 
    // Traverse the list and set right pointer to
    // end of list
    while (right.next != null)
        right = right.next;
 
    // Swap data of left and right pointer and move
    // them towards each other until they meet or
    // cross each other
    while (left != right && left.prev != right)
    {
 
        // Swap data of left and right pointer
        int t = left.data;
        left.data = right.data;
        right.data = t;
 
        // Advance left pointer
        left = left.next;
 
        // Advance right pointer
        right = right.prev;
    }
    return head;
}
 
// Driver code
public static void main(String args[])
{
    Node head = newNode(5);
    head = insert(head, 4);
    head = insert(head, 3);
    head = insert(head, 2);
    head = insert(head, 1);
 
    printList(head);
    System.out.println("List After Reversing");
    head=reverseList(head);
    printList(head);
 
}
}
 
// This code is contributed by Arnab Kundu


Python3
# Python3 Program to Reverse a List
# using Data Swapping
import math
 
class Node:
    def __init__(self, data):
        self.data = data
        self.next = None
 
def newNode(val):
    temp = Node(val)
    temp.data = val
    temp.prev =None
    temp.next = None
    return temp
 
def printList( head):
    while (head.next != None):
        print(head.data, end = "<-->")
        head = head.next
     
    print(head.data)
 
# Insert a new node at the head of the list
def insert(head, val):
    temp = newNode(val)
    temp.next = head
    (head).prev = temp
    (head) = temp
    return head
 
# Function to reverse the list
def reverseList( head):
    left = head
    right = head
 
    # Traverse the list and set right
    # pointer to end of list
    while (right.next != None):
        right = right.next
 
    # Swap data of left and right pointer
    # and move them towards each other
    # until they meet or cross each other
    while (left != right and left.prev != right):
 
        # Swap data of left and right pointer
        t = left.data
        left.data = right.data
        right.data = t
         
        # Advance left pointer
        left = left.next
 
        # Advance right pointer
        right = right.prev
     
    return head
 
# Driver code
if __name__=='__main__':
 
    head = newNode(5)
    head = insert(head, 4)
    head = insert(head, 3)
    head = insert(head, 2)
    head = insert(head, 1)
 
    printList(head)
    print("List After Reversing")
    head = reverseList(head)
    printList(head)
 
# This code is contributed by AbhiThakur


C#
// C# Program to Reverse a List using Data Swapping
using System;
 
class GFG
{
 
    public class Node
    {
        public int data;
        public Node prev, next;
    };
     
    static Node newNode(int val)
    {
        Node temp = new Node();
        temp.data = val;
        temp.prev = temp.next = null;
        return temp;
    }
     
    static void printList(Node head)
    {
        while (head.next != null)
        {
            Console.Write(head.data+ " <-> ");
            head = head.next;
        }
        Console.WriteLine( head.data );
    }
     
    // Insert a new node at the head of the list
    static Node insert(Node head, int val)
    {
        Node temp = newNode(val);
        temp.next = head;
        (head).prev = temp;
        (head) = temp;
        return head;
    }
     
    // Function to reverse the list
    static Node reverseList(Node head)
    {
        Node left = head, right = head;
     
        // Traverse the list and set right pointer to
        // end of list
        while (right.next != null)
            right = right.next;
     
        // Swap data of left and right pointer and move
        // them towards each other until they meet or
        // cross each other
        while (left != right && left.prev != right)
        {
     
            // Swap data of left and right pointer
            int t = left.data;
            left.data = right.data;
            right.data = t;
     
            // Advance left pointer
            left = left.next;
     
            // Advance right pointer
            right = right.prev;
        }
        return head;
    }
     
    // Driver code
    public static void Main(String []args)
    {
        Node head = newNode(5);
        head = insert(head, 4);
        head = insert(head, 3);
        head = insert(head, 2);
        head = insert(head, 1);
     
        printList(head);
        Console.WriteLine("List After Reversing");
        head=reverseList(head);
        printList(head);
     
    }
}
 
// This code has been contributed by 29AjayKumar


Javascript


输出:

1 <--> 2 <--> 3 <--> 4 <--> 5
List After Reversing
5 <--> 4 <--> 3 <--> 2 <--> 1

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