反向双向链表 |设置 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 现场工作专业课程和学生竞争性编程现场课程。