归并排序就是将两个或者两个以上的有序表合并为一个有序表的过程。将两个有序表合并成
一个有序表的过程称为2-路归并,2-路归并是最为简单的和常用的。
归并排序算法的思想是:
假设初始序列含有n个记录,则可看成是n个有序的子序列,每个子序列的长度是1,然后两
两归并,得到[n/2]个长度为2或1的有序子序列;再两两归并,如此重复,直至得到一个长度
为n的有序序列为止。
链表归并排序 (leetcode–148. 排序链表) 代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* sortList(ListNode*head) {
if (head == NULL || head -> next == NULL) {
return head;
}
ListNode * mid = findmid(head);
ListNode * left = head;
ListNode * right = mid -> next;
mid -> next = NULL;//把两个链表断开
return Merge(sortList(left), sortList(right));
}
//寻找中间节点
ListNode* findmid(ListNode*head) {
if (head == NULL || head -> next == NULL) {
return head;
}
ListNode * fast = head;
ListNode * slow = head;
while (fast -> next != NULL && fast -> next -> next != NULL) {
slow = slow -> next;
fast = fast -> next -> next;
}
return slow;
}
//合并两个有序链表
ListNode* Merge(ListNode*L, ListNode*R) {
if (L == NULL) {
return R;
}
if (R == NULL) {
return L;
}
ListNode * head = new ListNode(0);
ListNode * tail = head;
tail -> next = NULL;
while (L != NULL && R != NULL) {
if (L -> val > R -> val) {
tail -> next = R;
R = R -> next;
} else {
tail -> next = L;
L = L -> next;
}
tail = tail -> next;
}
if (L == NULL) {
tail -> next = R;
}
if (R == NULL) {
tail -> next = L;
}
return head -> next;
}
};