排序算法的执行效率
对于排序算法的执行效率一般会从这几个方面来衡量:
- 最好、最坏、平均情况的复杂度。
在分析排序算法的时间复杂度时,要分别给出最好情况、最坏情况、平均情况的时间复杂度。除此之外,还要说明最好和最坏的时间复杂度所对应的要排序的原始数据是什么样的。
- 时间复杂度的常数、系数、低阶。
时间复杂度返应的是数据规模n很大时候的一个增长趋势,所以它表示会忽略、系数、常数和低阶,但在软开发中,我们需要排序的数据可能是10、100、1000这样小规模的数据,所以对同一阶时间复杂度的排序算法性能对比的时候,需要把常数、系数和低阶考虑进去。
- 比较次数和交换(或移动)次数
基于比较的排序算法执行过程中,会涉及两种操作,一是比较元素的大小,二是元素的交换或移动,所以我们在分析排序算法的执行效率的时候,应该把次数和交换(或移动)次数也考虑进去。
排序算法的内存消耗
算法的内存消耗可以通过空间复杂度来衡量,排序算法也同样如此,在排序算法的空间复杂还引入了一个新的概念,原地排序,原地排序就是空间复杂度为O(1)的排序算法。
排序算法的稳定性
仅仅用算法的执行效率与内存消耗来衡量排序算法的好坏是不够的,还有一个非常重要的指标,排序算法的稳定性。稳定性,如果待排序的序列中存在值相等的元素,经过排序之后,相等的元素原有的先后顺序不变。
举个例子,待排序的数据为2,4,6,5,6,8,按从小到大进行排序就是2,4,5,6,6,8,
这组数据中存在两个6,经过排序算法后,如果两个6的先后顺序发生了改变,那称这种算法为不稳定的排序算法、如果两个6的先后顺序不变,那称这种算法为稳定排序算法。
为什么要考察排序算法的稳定性呢?
在排序算法的一般示例中,都是拿整数举例,这种数据集对于排序算法的稳定性当然没有要求,但是,在实际的软件开发中,待排序的不是整数,而是一组对象,我们按对象的某个属性进行排序。
还是举个例子,现在需要对电商的商品进行排序,商品有两个属性,一个是商品的上架时间、一个是商品的金额,如果我们现在有1万条商品数据,需要按商品的金额进行从小到大排序,对于金额相同的商品,希望按照上架的时间由近至远排序。
对于这样一个排序的需求,有多种实现方案,先说最先想到的吧,先按商品的金额进行排序,针对金额相同的数据,再按上架的时间进行由近至远行排序,这个思路可以实现,但实现会非常的复杂。
再来看另外一种实现方案,借助稳定的排序算法,对这组数据进行排序,排序思路是这样子:先按上架时间进行排序,再借助稳定排序按时间进行排序,就可以实现。为什么可以呢?还是来举一个具体的示例吧!
现在有一组数据:
商品名称 | 商品金额 | 上架时间 |
iphone | 5050 | 2019-10-15 07:37:00 |
huawei | 5050 | 2019-10-10 09:00:00 |
oppo | 1288 | 2019-10-01 08:00:00 |
vivo | 2199 | 2019-10-02 09:00:00 |
现在要对这组数据进行排序,先按商品金额,对于金额相同的,按时间由近至远排序。
- 先按上架时间进行排序
商品名称 | 商品金额 | 上架时间(时间倒序) |
iphone | 5050 | 2019-10-15 07:37:00 |
huawei | 5050 | 2019-10-10 09:00:00 |
vivo | 2199 | 2019-10-02 09:00:00 |
oppo | 1288 | 2019-10-01 08:00:00 |
- 借助稳定的排序算法,按金额进行排序(稳定排序算法不会改变值相同元素的先后顺序)
商品名称 | 商品金额 | 上架时间 |
oppo | 1288 | 2019-10-01 08:00:00 |
vivo | 2199 | 2019-10-02 09:00:00 |
iphone | 5050 | 2019-10-15 07:37:00 |
huawei | 5050 | 2019-10-10 09:00:00 |
总结
加以整理成表格就是
算法名称 | 最好情况时间复杂度 | 最好情况的原始数据 | 最坏情况时间复杂度 | 最坏情况的原始数据 | 平均情况时间复杂度 | 是否基于比较 | 空间复杂度 | 是否稳定排序算法 |
|
|
|
|
|
|
|
|
|