add mergeSort

This commit is contained in:
ShusenTang 2020-06-30 20:29:36 +08:00 committed by GitHub
parent 6ccf6c02ae
commit b60b313305
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -48,4 +48,53 @@ void quick_sort(vector<int> &arr, int left, int right){
``` ```
## 2. 归并排序 ## 2. 归并排序
TODO ### 2.1 算法描述
归并排序采用的是分治法Divide and Conquer思想。基本步骤是
1. 拆分:将原序列划分成子序列,然后假设子序列已经有序;
2. 合并:将有序的子序列合并,得到完全有序的序列;
归并排序具体有两种思路:一种是自上而下递归地归并,另一种是自下而上迭代地归并。
时间复杂度最坏、平均时间复杂度均为O(nlogn)。
### 2.2 代码
这里给出归并排序的典型应用:链表排序的代码,采用的是自上而下归并。
``` C++
ListNode* mergeSort(ListNode *head){
if(!head || !head -> next) return head;
ListNode *pre_slow = NULL, *slow = head, *fast = head;
while(fast && fast -> next){
pre_slow = slow;
slow = slow -> next;
fast = fast -> next -> next;
}
pre_slow -> next = NULL; // 1.1 divide into sublists
ListNode *l1 = mergeSort(head); 1.2 mergeSort sublists
ListNode *l2 = mergeSort(slow);
return merge2SortedLists(l1, l2); // 2. merge
}
ListNode* merge2SortedLists(ListNode *l1, ListNode *l2){
ListNode *head = new ListNode(0), *p = head;
while(l1 && l2){
if(l1 -> val <= l2 -> val){
p -> next = l1;
p = p -> next;
l1 = l1 -> next;
}
else{
p -> next = l2;
p = p -> next;
l2 = l2 -> next;
}
}
if(l1) p -> next = l1;
if(l2) p -> next = l2;
p = head -> next; delete head;
return p;
}
```