nlogn排序
自顶向下的递归Merge Sort
分成一半,再逐渐归并
二分法达到不同的层级,每个层级用O(N)的算法来做事情8 6 2 3
| 1 5 7 4
2 3 6 8
| 1 4 5 7
1 2 3 4 5 6 7 8
需要开辟同样大小的临时空间,来辅助完成归并过程
(即需要O(N)的额外空间来完成排序)
3个索引位置
i,j指向的是当前正在考虑的元素
k 指向的是比较之后,最终应该放到的数组的位置(指下一个需要放的位置)
基础版本
|
|
Random情况下
n = 10 0000
排序算法 | 所用时间 |
---|---|
Merge Sort | 0.077s |
Insertion Sort | 37.266s |
但是在数值近乎有序的情况下,Insertion Sort
效果要好于Merger Sort
近乎有序情况下(10 0000中有100个数据调换位置)
n = 10 0000
排序算法 | 所用时间 |
---|---|
Merge Sort | 0.051s |
Insertion Sort | 0.027s |
改进版本1
只在arr[mid] > arr[mid+1]的情况下才merge
近乎有序情况下(10 0000中有100个数据调换位置)
n = 10 0000
排序算法 | 所用时间 |
---|---|
Merge Sort | 0.014s |
Insertion Sort | 0.027s |
改进版本2
当元素数量比较少的时候,用插入排序
- 因为当元素数量比较少的时候,元素近乎有序的可能性比较大
- 数量级前面的系数,
插入排序
比归并排序
要小12345678910111213141516// 递归使用归并排序,对arr[l……r]的范围内进行排序template<typename T>void __mergeSort(T arr[], int l, int r){// if(l >= r) return;** if(r - l <= 15){insertionSort(arr, l, r);return;}**int mid = l + (r - l)/2;__mergeSort(arr, l, mid);__mergeSort(arr, mid+1, r);if(arr[mid] > arr[mid+1])__merge(arr, l, mid, r);}
自底向上的迭代Merge Sort
|
|
近乎有序情况下(10 0000中有100个数据调换位置)
n = 10 0000
排序算法 | 所用时间 |
---|---|
Merge Sort | 0.03s |
Insertion Sort | 0.065s |
注意两部分越界:
- 第二部分起始超过n
- 第二部分结束部分超过n
统计来说,递归的稍微快一点
但迭代的方法可以对链表进行排序(没有要求用数组)
Quick Sort
每次选好一个元素,想办法把它移到(在已经排好序情况下)的位置
之后,分别对小于4的部分和大于4的部分分别递归地使用快速排序
Partition
将数组元素分成两个部分
e>v
直接放在>
v的后面,然后i++
e<
v
先交换,然后j++,i++
结果

基础版Quick Sort
|
|
排序算法 | 所用时间 |
---|---|
Merge Sort | 0.029s |
Merge SortBU | 0.031s |
Quick Sory | 0.006s |
但是在近乎于有序的情况下,这种快速排序很慢
基于logn层的,归并排序可以保证每次都是平均分
最坏的情况
改进1—随机选择pivot
|
|
|
|
随机选择pivot并与第一个元素交换
此时,最坏时间复杂度仍然为O(N^2),但是退化到这种最坏情况的可能下近乎为0(需要保证每次选择的pivot均为最小值)
在元素近乎有序
的情况下明显好于partition1
改进2—双指针+均衡分配相等元素
当近乎有序的情况下,快速排序仍然会很慢,退化成O(N^2)
可能会造成分成的两块极度不均衡
最大的区别:
把等于v的元素分散到两部分
|
|
在存在大量重复元素
的情况下要明显好于partition3
Quick Sort 3 ways(三路快速排序)

1) e ==v
2) e < v
与==v的第一个元素交换
3) e > v
与gt-1交换,成为大于v的第一个元素(接着gt–)
结果
然后只需要将l和lt交换即可
优点:不需要对大量==v的元素交换,在存在大量==v的元素的时候相当可以
在测试中,三路快排在存在大量重复元素的数组中性能要远远好于其他,(但其他case稍稍慢一点点)
虽然是nlogn的算法,但快速排序在性能上要好于归并排序
一般系统级程序中,多用quickSort3Ways
因为它在处理大量重复键值的情况下优势明显,在处理其他情况性能也可以保障
Merge Sort 和 QuickSort的衍生问题
Merge Sort和 Quick Sort都使用了分治算法
思考:前人是如何想出来的