基本排序方法有:
- 插入排序——直接插入排序、折半插入排序、2-路插入排序、希尔排序
- 交换排序——冒泡排序、快速排序
- 选择排序——简单选择排序、堆排序、锦标赛排序
- 归并排序——
- 基数排序——
关系:直接插入排序---优化--->希尔排序;折半插入排序---优化--->2-路插入排序;冒泡排序---优化-->快速排序;简单选择排序---优化-->堆排序、锦标赛排序;
计数排序、桶排序与基数排序感觉像哈希,
补充: 拓扑排序 对一个有向无环图(Directed Acyclic Graph简称DAG)G进行排序,是将G中所有顶点排成一个线性序列,使得图中任意一对顶点u和v,若<u,v> ∈E(G),则u在线性序列中出现在v之前。
比较全的总结:
理论 | ||
---|---|---|
交换排序法 | ||
选择排序法 | ||
插入排序法 | ||
归并排序法 | ||
分布排序法 | ||
混合排序法 | ||
其他 |
按照存储方式分为三类:
- 线性表
- 静态链表(表排序)
- 线性表+指针(地址排序)
1.排序算法分类,稳定性和时空复杂度:
选择排序算法时考虑的因素:
(1)待排序的记录数目n的大小;
(2)记录本身数据量的大小,也就是记录中除关键码外的其他信息量的大小;
(3)关键码的结构及其分布情况;
(4)对排序稳定性的要求。
2.适用特点:
特点 | ||
插入排序 | 直接插入排序 | 数据基本有序时,可以减少数据交换和移动次数,提高效率 |
希尔排序 | 简单,适用于小数据量情况 | |
交换排序 | 冒泡排序 | 实际使用中效率较低,对数据有序性非常敏感 |
快速排序 | 分治,自顶向下。理论上最好的方法,应用广泛; 如果数据量大而且数据全部放在内存中,那么快速排序是首选的排序方法 | |
选择排序 | 简单选择排序 | 对有序性不敏感,交换次数少 |
堆排序 | 不需要递归,适合大数据量,可用来实现优先队列 | |
其他排序 | 合并排序 | 分治,自底向上。对有序性不敏感,需要辅助空间, |
非基于比较 | 计数排序 | 数据范围需要不大 |
基数排序 | 关键字需要可分解 | |
桶排序 | 数据分布均匀 |
在数据量不大时,所有排序算法性能差别不大。有文章指出,高级排序算法在元素个数多于1000 时,性能才出现显著提升。在90%的情况下,我们存储的元素个数只有几十到上百个而已,比如进程数、窗口个数和配置信息等等的数量都不会很大,冒泡排序其实是更好的选择。
3.算法选择
稳定性:简单排序算法、锦标赛排序、归并排序和基数排序、计数排序是稳定的
大部分优化排序如希尔排序O(n^(3/2))、快速排序、简单选择排序(有争议)、堆排序是不稳定的
按照时间复杂度分为三类:
- 简单排序O(n^2)---直接插入排序、折半插入排序、2-路插入排序、冒泡排序
- 优化排序O(n*logn)---希尔排序O(n^(3/2))、快速排序、堆排序、锦标赛排序、归并排序
- 基数排序O(d*n)---基数排序
根据网站Sorting Algorithm Animations中的演示,可以清晰的看出:
等量的数据排序时:
- 原始序列无序时, 堆排序、希尔排序、归并排序、快速排序是较快的,其次是插入排序,再是冒泡排序,最后是选择排序。
- 在较为有序时,插入排序、冒泡排序时最快的,其次是希尔排序,再者是归并、堆排序和快速排序,最后是选择排序。
- 在逆序时,堆排序、希尔排序、归并排序、快速排序时较快的,其次是插入排序和冒泡排序,最后是选择排序。
- 在有个别特例时,希尔排序、堆排序和归并排序以及插入排序时较快的,其次是冒泡排序最后是选择排序,快速排序不同实现方法最快(3路)如插入排序,最差(2路)如冒泡排序。
选择排序的速度似乎总是最慢的,但是对于数据量较小,对稳定性又不做要求时,选择排序还是可用的。
- 堆排序、希尔排序、归并排序、快速排序、选择排序对数据原始状态不敏感。
- 插入排序和冒泡排序在逆序时表现较差,在基本有序时表现最好。
参考: