📅  最后修改于: 2023-12-03 14:50:32.396000             🧑  作者: Mango
双向链表合并排序是一种常见的排序算法,其核心思想是将两个已排序的双向链表合并成一个排序好的双向链表。本文将介绍双向链表合并排序的实现过程和C代码。
双向链表是一种数据结构,其特点是每个节点包含两个指针,一个指向前一个节点,一个指向后一个节点。这种数据结构在链表操作中非常常见,因为它提供了方便的反向遍历功能。
typedef struct node{
int data;
struct node* next;
struct node* prev;
}Node;
上面的代码定义了一个双向链表节点结构体。
双向链表合并排序算法分为三个部分:
/* 分割链表,返回链表后半部分的开始节点 */
Node* split(Node* head) {
Node* fast = head;
Node* slow = head;
/* 将fast指针定位到链表中点 */
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
}
Node* temp = slow->next;
slow->next = NULL;
return temp;
}
/* 合并两个已排序的链表 */
Node* merge(Node* l1, Node* l2) {
Node dummy;
dummy.next = NULL;
Node* tail = &dummy;
while (l1 && l2) {
if (l1->data < l2->data) {
tail->next = l1;
l1 = l1->next;
} else {
tail->next = l2;
l2 = l2->next;
}
tail->next->prev = tail;
tail = tail->next;
}
tail->next = l1 ? l1 : l2;
tail->next->prev = tail;
return dummy.next;
}
/* 递归排序 */
Node* sortList(Node* head) {
if (!head || !head->next)
return head;
Node* l1 = head;
Node* l2 = split(head);
l1 = sortList(l1);
l2 = sortList(l2);
return merge(l1, l2);
}
typedef struct node{
int data;
struct node* next;
struct node* prev;
}Node;
/* 分割链表,返回链表后半部分的开始节点 */
Node* split(Node* head) {
Node* fast = head;
Node* slow = head;
/* 将fast指针定位到链表中点 */
while (fast && fast->next) {
fast = fast->next->next;
slow = slow->next;
}
Node* temp = slow->next;
slow->next = NULL;
return temp;
}
/* 合并两个已排序的链表 */
Node* merge(Node* l1, Node* l2) {
Node dummy;
dummy.next = NULL;
Node* tail = &dummy;
while (l1 && l2) {
if (l1->data < l2->data) {
tail->next = l1;
l1 = l1->next;
} else {
tail->next = l2;
l2 = l2->next;
}
tail->next->prev = tail;
tail = tail->next;
}
tail->next = l1 ? l1 : l2;
tail->next->prev = tail;
return dummy.next;
}
/* 递归排序 */
Node* sortList(Node* head) {
if (!head || !head->next)
return head;
Node* l1 = head;
Node* l2 = split(head);
l1 = sortList(l1);
l2 = sortList(l2);
return merge(l1, l2);
}
int main() {
Node n1, n2, n3, n4, n5;
n1.data = 3;
n1.next = &n2;
n1.prev = NULL;
n2.data = 1;
n2.next = &n3;
n2.prev = &n1;
n3.data = 4;
n3.next = &n4;
n3.prev = &n2;
n4.data = 2;
n4.next = &n5;
n4.prev = &n3;
n5.data = 5;
n5.next = NULL;
n5.prev = &n4;
Node* head = &n1;
head = sortList(head);
while (head) {
printf("%d ", head->data);
head = head->next;
}
return 0;
}