接下来文章将会讲述四种排序算法的实现和可行性证明。只有证明一个算法的正确性,才算理解一种算法。
快速排序
步骤
1)从需要排序的数组选中一个作为Key,比Key小的放在右边,比Key大的放在左边。
2 )Key右侧的元素重复步骤1)
3)Key右侧的元素重复步骤1)
观察源码即可找到实现步骤一效果的方法。
可行性证明
题设
1 |
|
假设数组为 a[] ,Key的下标为k,数组范围为0-n。
1 |
|
优点和缺点
优点:空间复杂度为 O(N)
缺点:时间复杂度O(Nlog(N)),但是不稳定。Key的选择很关键,选不好复杂度就会变为N的平方。
优化方法:选择数组头部中间尾部,三个元素中间值作为Key。
1 |
|
归并排序
步骤
1)将数组分为两个大小相同的数组(有可能大小相差1),继续分割数组,直到数组大小为1.
2)现在从同一个数组分割来的两个数组都为升序,将两个数组合并为一个升序的数组。
3)重复步骤 2)直到整个数组被合并
原理
典型的分治算法。通过子序列的有序性,保证自身的有序性。
优点缺点
优点:时间复杂度为O(Nlog(N)) 并且极其稳定
缺点:空间复杂度为O(2N)),比较节省空间的场合不适用,尤其是比较大的数组
1 |
|
堆排序
步骤
- 最大堆:完全二叉树,所有根节点的子节点小于等于本身
1)N个节点的树,构建为最大堆。
2)根节点与树最后一个叶子节点交换。
3)除去尾部的交换节点之后的树,构造为最大堆
4)重负步骤2)
优点缺点
优点 复杂度O(Nlog(N)) 空间复杂度为O(N)
缺点 构建最大堆浪费不少时间
源码
1 |
|
基数排序
步骤
1)将需要排序的数组list中的数字根据他们的个位数字i放到对应的数组bucket[i]的末尾。
2)从0-9依次将bucket中的数字放置到需要排序的数组list。
3)接下来是十位、百位,重复类似步骤1),指导数组list中的所有元素该位置都没有数字。
优点和缺点
优点:
时间复杂度低O(Mlog(N)).(N为排序数字个数M为最大位)对于N大M小的情况尤为突出。
可以实现相同大小的数字,依旧保持先后顺序
缺点
辅助空间需求要求比较大
M大N小时,性能下降
试用的排序类型比较少,整数最适合
缺点
源码
1 |
|