算法导论-1、排序算法总结
提纲:
- 比较排序
- 插入排序
- 分治排序/归并排序
- 堆排序
- 快速排序
- 线性时间排序
- 计数排序
- 基数排序
- 桶排序
一、比较排序
1) 插入排序
基本思想:就像排扑克牌一样,从小到大(当然也可以从大到小,本案例考虑从小到大)依次列开;当拿到新手牌时,插入到新的位置,使得:在其左边的都比它小,在它右边的都比它大。
算法效率:考虑到最坏的情况(是按从大到小的排列的),需要移动
,所以其最坏运行时间为:
优缺点:原理简单,易于实现,但效率较低。
2)分治排序/归并排序
基本思想:利用分治、递归的思想,将问题分解,然后合并。还是扑克牌的例子,如果桌子上有两副已经排好序的牌,最小的牌在顶端,现在要把它们按次序合成一副:方法就是选择两
堆中较小的一张,从该牌在其堆顶取出,然后放在输出堆。重复这个步骤,直至结束。基本步骤包括两步:1)以中点分解。2)合并。
算法效率:合并
的时间效率是
,所以整个算法的运行时间为:
,利用递归树分析,可求解出最后的运行时间为:
优缺点:时间效率提高了,但消耗了空间效率。
3)堆排序
基本思想:(二叉)堆是利用数组实现的,它相较于(2)的分治排序,具有空间原址性:任何时候都需要常数个额外的空间存储临时空间,而且时间复杂度与分治排序一样为:
。
它是利用二叉树的性质,构建最大堆,即父节点不小于子节点,然后进行维护、排序的。
步骤:1)堆维护,如果更改
的值,
函数确保堆依然是最大堆.
2 )最大堆的构建:已知一个矩阵,利用(1)的函数去构建一个最大堆.
3 )堆排序,依次去调用最大堆的第一值,倒序输出即可得到一个有序数组.
算法效率:
的运行时间与二叉树的高度成正比,所以为
,而堆的构建时间为:
.而堆排序,调用一次堆的构建,还有n次堆维护,所以最后时间效率为:
4)快速排序
基本思想:快速排序,糅合了插入排序和分治排序的思想:首先将末尾元素做哨兵,插入到一个位置,使得在它之前的元素均比它小,在它之后的元素均比它大;这样以后就可以将数组分成
了前后两部分,分别递归使用分治,就可得到结果了。
算法的效率:1)最坏的情况,也就是已经排好序的情况,因为此时每次分化都是
和
,此时的运行时间为:
,效率跟插入算法一样;
2)最好的情况,也就是每次递归,子问题规模均为:
,此时效率为:
.
3)平均的情况下效率为
优缺点:虽然在最坏的情况下,其效率为
,但它的期望时间复杂度却是
,而且其隐含的常数因子非常小;此外,快速排序也是原址排序,在实际应用中是很好的选择。
二、线性时间排序
1)计数排序
基本思想:如果数组数值均在
之间,则建立一个计数数组,统计每个数值出现的次数,然后累加就可以得知每个值对应在排序后的位置了.
算法的效率:因为不是比较排序,它的运行时间有赖于区间
的大小,如果
,那么排序的运行时间为:
优缺点:首先稳定性,如果连个值相同的话,排序后不会改变它们的先后顺序;然后比较适合与数组中重复元素很多的情况。只能针对整数排序,对于浮点类型,无法统计计数。
2)基数排序
基本思想:很直观的排序方式,如果我们要在电话薄上找一个人的电话号码,而电话号码一般是按联系人的拼音排序的。如果找“Xiao Ming”,首先就是找X开头的,然后依次类推了。
但与我们直观不同的是,基数排序是按照最低有效位排序的,从最低位按从小到大排序,然后是上一位,最后最高位排列出来的就是从小到大的排列顺序。
算法效率:如果有
位数,每位数有
个可能值,那么运行时间就为:
.
优缺点:在一位数排序时,需要依赖于一个稳定排序方法。本案例中,使用计数排序方法.
3)桶排序
基本思想:假设输入是均匀独立地分布在区间的小数,对这样的数组排序。