数据结构反转双向链表 | 第三套

1,156 阅读1分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

给定一个双向链表,任务是反转给定的双向链表。

例如,请参见下图。

(a) 原始双向链表

image.png

(b) 反向双向链表

image.png

这是反转双向链表的简单方法。我们需要做的就是交换所有节点的 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)
我们还可以交换数据而不是指针来反转双向链表。用于反转数组的方法可用于交换数据。如果数据项的大小更大,则与指针相比,交换数据的成本可能更高。
如果您发现上述任何代码/算法不正确,请写评论,或者找到解决相同问题的更好方法。

方法二: 

同样的问题也可以通过使用堆栈来完成。 

步骤:

  1. 继续将节点的数据压入堆栈。-> O(n)
  2. 不断弹出元素并更新双向链表
#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)的时间复杂度。