2-算法-排序算法
排序方法 |
平均时间 |
最坏时间 |
最好时间 |
空间 |
稳定 |
冒泡排序 |
n2 |
n2 |
n |
1 |
Y |
选择排序 |
n2 |
n2 |
n2 |
1 |
N |
插入排序 |
n2 |
n2 |
n |
1 |
Y |
希尔排序 |
n1.3 |
n2 |
n |
1 |
N |
归并排序 |
nlog2n |
nlog2n |
nlog2n |
n |
Y |
快速排序 |
nlog2n |
n2 |
nlog2n |
(log2n) - n |
N |
堆排序 |
nlog2n |
nlog2n |
nlog2n |
1 |
N |
计数排序 |
|
|
|
|
|
桶排序 |
|
|
|
|
|
基数排序 |
|
|
|
|
|
一般的讲解都是用进行从小到大的升序排序
- 冒泡排序:两两比较,将大的往后移。设置标志位记录此次遍历顺序是否有变动,可以是最好时间复杂度变为n。
- 选择排序:每次循环标记出最小的,循环结束后将标记出的最小值与前面的值进行不相邻元素交换,所以选择排序是不稳定的排序。比如5,8,5,2在第一次交换时会将第一个5交换到后面。
- 插入排序:类似于打扑克牌,维护好前n个的序列,为N+1找好位置放入。在比较的同时将数组内元素后移,这样不必借用额外的空间,所以空间复杂度是O(1)。
- 希尔排序(缩小增量排序):设置gap=N/2,相隔gap的为一组,组内进行插入排序;gap=gap/2,组内进行插入排序。
- 归并排序:分而治之,在“治”的阶段充分利用了子序列是已经排好序这一特点。归并排序需要一个与原排序数组一样大的辅助数组空间,所以空间复杂度为O(n)。(《数据结构c++描述版》p424)
- 快速排序:找基准,比基准小的放一边,大的放另一边(采用交换的方式);根据基准“分”,再使用“基准-分治”的方式治。因为在完全倒序的情况下会导致分的不均匀,所以算法的最差复杂度依然是n2。快排是不稳定的排序比如[5,8,8,4]在遇到4的时候会导致第一个8移动到最后。快速排序算法是递归排序算法,每一层递归需要记录相应的指针和参数,所以空间复杂度为log2n,在差的情况中也会是n(《数据结构c++描述版》p408)。
- 堆排序:数组转化为最大堆数组。
- 将堆顶元素与数组末尾元素交换
- 末尾元素的交换导致最大堆的破坏,重新维护数组。
- 重复步骤1,2,直到所有元素取完。
- 计数排序:只适用于对整数排序。先转换数组,原数组-》arr[i]=i的出现次数-》arr[i]=i值在最终数组中的角标。转换完数组,从最后开始遍历原数组。
- 桶排序:使用哈希的思想
- 基数排序:先按个位数入桶-》按先进先出的顺序出桶-》按十位数入桶-》出桶……
不稳定的算法多数存在不相邻元素的交换