小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
给定一个双向链表,任务是反转给定的双向链表。
例如,请参见下图。
(a) 原始双向链表
(b) 反向双向链表
这是反转双向链表的简单方法。我们需要做的就是交换所有节点的 prev 和 next 指针,更改头部(或开始)的 prev 并更改最后的头部指针。
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
int data;
Node *next;
Node *prev;
};
void reverse(Node **head_ref)
{
Node *temp = NULL;
Node *current = *head_ref;
while (current != NULL)
{
temp = current->prev;
current->prev = current->next;
current->next = temp;
current = current->prev;
}
if(temp != NULL )
*head_ref = temp->prev;
}
void push(Node** head_ref, int new_data)
{
Node* new_node = new Node();
new_node->data = new_data;
prev is always NULL */
new_node->prev = NULL;
new_node->next = (*head_ref);
if((*head_ref) != NULL)
(*head_ref)->prev = new_node ;
(*head_ref) = new_node;
}
void printList(Node *node)
{
while(node != NULL)
{
cout << node->data << " ";
node = node->next;
}
}
int main()
{
/* Start with the empty list */
Node* head = NULL;
push(&head, 2);
push(&head, 4);
push(&head, 8);
push(&head, 10);
cout << "原始链表" << endl;
printList(head);
reverse(&head);
cout << "\n反向链表" << endl;
printList(head);
return 0;
}
输出:
原始链表
10 8 4 2
反向链表
2 4 8 10
时间复杂度: O(N),其中 N 表示双向链表中的节点数。
辅助空间:O(1)
我们还可以交换数据而不是指针来反转双向链表。用于反转数组的方法可用于交换数据。如果数据项的大小更大,则与指针相比,交换数据的成本可能更高。
如果您发现上述任何代码/算法不正确,请写评论,或者找到解决相同问题的更好方法。
方法二:
同样的问题也可以通过使用堆栈来完成。
步骤:
- 继续将节点的数据压入堆栈。-> O(n)
- 不断弹出元素并更新双向链表
#include <bits/stdc++.h>
using namespace std;
struct LinkedList {
struct Node {
int data;
Node *next, *prev;
Node(int d)
{
data = d;
next = prev = NULL;
}
};
Node* head = NULL;
void reverse()
{
stack<int> st;
Node* temp = head;
while (temp != NULL) {
st.push(temp->data);
temp = temp->next;
}
temp = head;
while (temp != NULL) {
temp->data = st.top();
st.pop();
temp = temp->next;
}
}
void Push(int new_data)
{
Node* new_node = new Node(new_data);
new_node->prev = NULL;
new_node->next = head;
if (head != NULL) {
head->prev = new_node;
}
head = new_node;
}
void printList(Node* node)
{
while (node) {
cout << node->data << " ";
node = node->next;
}
}
};
int main()
{
LinkedList list;
list.Push(2);
list.Push(4);
list.Push(8);
list.Push(10);
cout << "原始链表 " << endl;
list.printList(list.head);
list.reverse();
cout << endl;
cout << "反向链表是 " << endl;
list.printList(list.head);
}
输出
原始链表
10 8 4 2
反向链表是
2 4 8 10
时间复杂度: O(N)
辅助空间: O(N)
在这种方法中,我们遍历链表一次并将元素添加到堆栈中,然后再次遍历整个以更新所有元素。整个需要2n时间,也就是O(n)的时间复杂度。