关于时间复杂度
平方阶 (O(n2)) 排序 各类简单排序:直接插入、直接选择和冒泡排序。
线性对数阶 (O(nlog2n)) 排序 快速排序、堆排序和归并排序;
O(n1+§)) 排序,§ 是介于 0 和 1 之间的常数。 希尔排序
线性阶 (O(n)) 排序 基数排序,此外还有桶、箱排序。
关于稳定性
稳定的排序算法:冒泡排序、插入排序、归并排序和基数排序。
不稳定的排序算法:选择排序、快速排序、希尔排序、堆排序。
名词解释:
n:数据规模
k:"桶"的个数
In-place:占用常数内存,不占用额外内存
Out-place:占用额外内存
稳定性:排序后 2 个相等键值的顺序和排序之前它们的顺序相同
包含以下内容:
1、冒泡排序
2、选择排序
3、插入排序
4、希尔排序
5、归并排序
6、快速排序
7、堆排序
8、计数排序
9、桶排序
10、基数排序
(以上是从菜鸟教程复制过来的,写的很好)
特别鸣谢
实际场合中,快排对于数据量大,数据分布随机的平均效率高于堆排序,但如果数据大部分有序发现快排明显退化的时候会切换到堆排,快排递归到比较小的数据量的时候为了节约递归产生的空间,也会切换成插入排序;
1.冒泡排序
1)正序O(n)
2)反序O(n^2)
3)原地排序
4)交换次数少
也就是说,当基本正序时使用冒泡排序很快。
2、选择排序
1)无论什么数据进去都是 O(n²) 的时间复杂度。所以用到它的时候,数据规模越小越好。
2)优点:不占用额外的内存空间。(即原地操作)
3)使用场景:当空间复杂度要求较高时,可以考虑选择排序。
4)原地排序
3、插入排序
1)正序O(n)
2)反序O(n^2)
3)可以用二分查找来优化插入的过程
4)使用场景:当数据量小,并且已经趋于有序的时候
5)原地排序
4、希尔排序
(缩小增量排序)
用插入排序将局部有序的数组排序
1)希尔排序的时间的时间复杂度:
2)使用场景:希尔排序没有快速排序算法快 ,在中等大小规模表现良好
3)希尔算法在最坏的情况下和平均情况下执行效率相差不是很多
4)专家们提倡:几乎任何排序工作在开始时都可以用希尔排序,若在实际使用中证明它不够快,再改成快速排序这样更高级的排序算法
5、归并排序
1)始终都是 O(nlogn) 的时间复杂度。代价是需要额外的内存空间。
2)使用场景
+适用于链表排序,可以在O(nLogn)时间内排序。通常是链表排序的首选
+计算逆序对个数(每次归并都会出现新的逆序对,因为以前它们两未曾相见)
+用于外部排序(External Sorting)
归并在外部排序,比如磁盘文件的情况下比快排好,因为快排很依赖数据的随机存取,而归并是顺序存取,对磁盘这种外存比较友好
6、快速排序
这里就不贴图了,大一时手撕了快排的代码,一直印象很深刻。(主要动图描述的不清楚)
1)平均状况,Ο(nlogn) 。
2)最坏,Ο(n2) (但这种状况并不常见)(比如说顺序数列的快排)
3)大多数情况下都比平均时间复杂度为 O(n logn) 的排序算法表现要更好
4) O(nlogn) 记号中隐含的常数因子很小,比复杂度稳定等于 O(nlogn) 的归并排序要小很多。所以,对绝大多数顺序性较弱的随机数列而言,快速排序总是优于归并排序。
(就是说nlogn前面的常数很小)
5)适用场景:
适用于大量数据的比较
比较的元素越多,快速排序比冒泡排序越快
当对于数据量大,数据分布高度随机的场景,快速排序的平均效率要高于 堆排序和 归并排序
7、堆排序
就是用堆来排序。
1)原地排序
2)对于Top- K问题,堆排序性能的下限(时间复杂度O(nlogn)要高于快排;
3)快排和堆排都是不稳定排序
4)使用场景;
+优先级队列
+利用堆求topK
5)缺点:在堆排序中有较多次数的交换
8、计数排序
++cnt[i]
9、桶排序
先各自装入桶中,再在桶内进行排序
桶内排序可以选择不同的排序方式
1)尽量增加桶的数量
2)映射函数能够将输入的 N 个数据均匀的分配到 K 个桶中
3)桶内排序算法影响性能
4)最快:均匀分配到各个桶中
5)最慢:分配到一个桶中
10、基数排序
对数位排序