最近开始找工做了,总结一些基本问题供复习。html
排序算法能够说是一项基本功,解决实际问题中常常遇到,针对实际数据的特色选择合适的排序算法可使程序得到更高的效率,有时候排序的稳定性仍是实际问题中必须考虑的,这篇博客对常见的排序算法进行整理,包括:插入排序、选择排序、冒泡排序、快速排序、堆排序、归并排序、希尔排序、二叉树排序、计数排序、桶排序、基数排序。算法
比较排序和非比较排序shell
常见的排序算法都是比较排序,非比较排序包括计数排序、桶排序和基数排序,非比较排序对数据有要求,由于数据自己包含了定位特征,全部才能不经过比较来肯定元素的位置。post
比较排序的时间复杂度一般为O(n2)或者O(nlogn),比较排序的时间复杂度下界就是O(nlogn),而非比较排序的时间复杂度能够达到O(n),可是都须要额外的空间开销。ui
比较排序时间复杂度为O(nlogn)的证实:url
a1,a2,a3……an序列的全部排序有n!种,因此知足要求的排序a1',a2',a3'……an'(其中a1'<=a2'<=a3'……<=an')的几率为1/n!。基于输入元素的比较排序,每一次比较的返回不是0就是1,这刚好能够做为决策树的一个决策将一个事件分红两个分支。好比冒泡排序时经过比较a1和a2两个数的大小能够把序列分红a1,a2……an与a2,a1……an(气泡a2上升一个身位)两种不一样的结果,所以比较排序也能够构造决策树。根节点表明原始序列a1,a2,a3……an,全部叶子节点都是这个序列的重排(共有n!个,其中有一个就是咱们排序的结果a1',a2',a3'……an')。若是每次比较的结果都是等几率的话(刚好划分为几率空间相等的两个事件),那么二叉树就是高度平衡的,深度至少是log(n!)。spa
又由于 1. n! < nn ,两边取对数就获得log(n!)<nlog(n),因此log(n!) = O(nlogn).htm
2. n!=n(n-1)(n-2)(n-3)…1 > (n/2)^(n/2) 两边取对数获得 log(n!) > (n/2)log(n/2) = Ω(nlogn),因此 log(n!) = Ω(nlogn)。blog
所以log(n!)的增加速度与 nlogn 相同,即 log(n!)=Θ(nlogn),这就是通用排序算法的最低时间复杂度O(nlogn)的依据。排序
1.稳定性比较
插入排序、冒泡排序、二叉树排序、二路归并排序及其余线形排序是稳定的;
选择排序、希尔排序、快速排序、堆排序是不稳定的。
2.时间复杂性比较
平均状况 | 最好状况 | 最坏状况 | |
归并排序 | O(nlogn) | O(nlogn) | O(nlogn) |
基数排序 | O(n) | O(n) | O(n) |
快速排序 | O(nlogn) | O(nlogn) | O(n2) |
希尔排序 | O(n1.5) | O(n) | O(n1.5) |
插入排序 | O(n2) | O(n) | O(n2) |
选择排序 |
O(n2) | O(n2) | O(n2) |
3.辅助空间的比较
线形排序、二路归并排序的辅助空间为O(n),其它排序的辅助空间为O(1);
4.其它比较
插入、冒泡排序的速度较慢,但参加排序的序列局部或总体有序时,这种排序能达到较快的速度。
反而在这种状况下,快速排序反而慢了。
当n较小时,对稳定性不做要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序。
若待排序的记录的关键字在一个明显有限范围内时,且空间容许是用桶排序。
当n较大时,关键字元素比较随机,对稳定性没要求宜用快速排序。
当n较大时,关键字元素可能出现自己是有序的,对稳定性有要求时,空间容许的状况下。
宜用归并排序。
当n较大时,关键字元素可能出现自己是有序的,对稳定性没有要求时宜用堆排序。
=============================================================================
相关知识介绍(全部定义只为帮助读者理解相关概念,并不是严格定义):
一、稳定排序和非稳定排序
简单地说就是全部相等的数通过某种排序方法后,仍能保持它们在排序以前的相对次序,咱们就
说这种排序方法是稳定的。反之,就是非稳定的。
好比:一组数排序前是a1,a2,a3,a4,a5,其中a2=a4,通过某种排序后为a1,a2,a4,a3,a5,
则咱们说这种排序是稳定的,由于a2排序前在a4的前面,排序后它仍是在a4的前面。假如变成a1,a4,
a2,a3,a5就不是稳定的了。
二、内排序和外排序
在排序过程当中,全部须要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序;
在排序过程当中,只有部分数被调入内存,并借助内存调整数在外存中的存放顺序排序方法称为外排序。
三、算法的时间复杂度和空间复杂度
所谓算法的时间复杂度,是指执行算法所须要的计算工做量。
一个算法的空间复杂度,通常是指执行这个算法所须要的内存空间。
排序的稳定性和复杂度
不稳定:
选择排序(selection sort)— O(n2)
快速排序(quicksort)— O(nlogn) 平均时间, O(n2) 最坏状况; 对于大的、乱序串列通常认为是最快的已知排序
堆排序 (heapsort)— O(nlogn)
希尔排序 (shell sort)— O(nlogn)
基数排序(radix sort)— O(n·k); 须要 O(n) 额外存储空间 (K为特征个数)
稳定:
插入排序(insertion sort)— O(n2)
冒泡排序(bubble sort) — O(n2)
归并排序 (merge sort)— O(n log n); 须要 O(n) 额外存储空间
二叉树排序(Binary tree sort) — O(nlogn); 须要 O(n) 额外存储空间
计数排序 (counting sort) — O(n+k); 须要 O(n+k) 额外存储空间,k为序列中Max-Min+1
桶排序 (bucket sort)— O(n); 须要 O(k) 额外存储空间