
给定一个双向链表,编写一个函数,使用归并排序以递增的顺序对双向链表进行排序。
比如下面的双链表应该改成24810

单链表的归并排序已经讨论过了。这里的重要变化是在合并两个列表时也要修改前面的指针。
下面是双向链表归并排序的实现。
#include <bits/stdc++.h>
using namespace std;
class Node
{
public:
int data;
Node *next, *prev;
};
Node *split(Node *head);
复制代码
合并两个链表的函数
Node *merge(Node *first, Node *second)
{
// 如果第一个链表为空
if (!first)
return second;
// 如果第二个链表为空
if (!second)
return first;
// 选择较小的值
if (first->data < second->data)
{
first->next = merge(first->next,second);
first->next->prev = first;
first->prev = NULL;
return first;
}
else
{
second->next = merge(first,second->next);
second->next->prev = second;
second->prev = NULL;
return second;
}
}
复制代码
执行归并排序的函数
Node *mergeSort(Node *head)
{
if (!head || !head->next)
return head;
Node *second = split(head);
// 重复左半部分和右半部分
head = mergeSort(head);
second = mergeSort(second);
// 合并已排序的两半
return merge(head,second);
}
复制代码
在双向链表的开头插入新节点的实用函数
void insert(Node **head, int data)
{
Node *temp = new Node();
temp->data = data;
temp->next = temp->prev = NULL;
if (!(*head))
(*head) = temp;
else
{
temp->next = *head;
(*head)->prev = temp;
(*head) = temp;
}
}
复制代码
在向前和向后两个方向打印双向链表的实用函数
void print(Node *head)
{
Node *temp = head;
cout<<"使用下一个指针进行前向遍历\n";
while (head)
{
cout << head->data << " ";
temp = head;
head = head->next;
}
cout << "\n使用 prev 指针向后遍历\n";
while (temp)
{
cout << temp->data << " ";
temp = temp->prev;
}
}
复制代码
交换两个整数的实用函数
void swap(int *A, int *B)
{
int temp = *A;
*A = *B;
*B = temp;
}
复制代码
将一个双向链表 (DLL) 拆分为 2 个半大小的 DLL
Node *split(Node *head)
{
Node *fast = head,*slow = head;
while (fast->next && fast->next->next)
{
fast = fast->next->next;
slow = slow->next;
}
Node *temp = slow->next;
slow->next = NULL;
return temp;
}
复制代码
驱动程序
int main(void)
{
Node *head = NULL;
insert(&head, 5);
insert(&head, 20);
insert(&head, 4);
insert(&head, 3);
insert(&head, 30);
insert(&head, 10);
head = mergeSort(head);
cout << "排序后的链表\n";
print(head);
return 0;
}
复制代码
输出:
排序后的链表
使用下一个指针进行前向遍历
3 4 5 10 20 30
使用 prev 指针向后遍历
30 20 10 5 4 3
















