链表的归并排序类比于数组的归并排序,区别在于需要单独编写寻找中间结点的算法。给出实际代码:
#include <iostream>
using namespace std;
// 结点的定义
struct Node {
int data;
struct Node* link;
Node (int d = 0, struct Node* p = nullptr) {
data = d;
link = p;
}
};
// 处理2个递增的链表数据, len是元素的个数
void Merge(Node* head1, Node* head2, int len1, int len2) {
int* num = new int[len1 + len2];
int n1 = 0, n2 = 0, n = 0;
Node* p1 = head1, *p2 = head2;
while(n1 < len1 && n2 < len2) {
if(p1->data < p2->data) {
num[n++] = p1->data;
p1 = p1->link;
++n1;
} else {
num[n++] = p2->data;
p2 = p2->link;
++n2;
}
}
while(n1 < len1) {
num[n++] = p1->data;
p1 = p1->link;
++n1;
}
while(n2 < len2) {
num[n++] = p2->data;
p2 = p2->link;
++n2;
}
p1 = head1;
for(int i = 0; i < len1 + len2; ++i) {
p1->data = num[i];
p1 = p1->link;
}
delete[] num;
}
// 寻找中点
Node* Middle(Node* head, int len) {
int m = len / 2;
Node* mid = head;
while(m--) {
mid = mid->link;
}
return mid;
}
// 递归地归并排序
void MergeSort(Node* head, int len) {
if(len <= 1) {
return;
}
Node* mid = Middle(head, len);
int len1 = len / 2;
int len2 = len - len1;
MergeSort(head, len1);
MergeSort(mid, len2);
Merge(head, mid, len1, len2);
}
// 尾插法建立带有头结点的链表
Node* Create_Head_TailInsert(int n) {
if(n < 0) {
return nullptr;
}
Node* head = new Node;
Node* pre = head;
while(n--) {
int t;
cin >> t;
Node* p = new Node(t);
pre->link = p;
pre = p;
}
return head;
}
// 输出函数
void Print_Head(Node* head) {
Node* p = head->link;
while(p != nullptr) {
cout << p->data << " ";
p = p->link;
}
}
int main() {
int n;
cin >> n; // 输入元素的个数
Node* head = Create_Head_TailInsert(n);
MergeSort(head->link, n);
Print_Head(head);
return 0;
}