排序算法
冒泡排序法
实现
- 对相邻的元素排序
- 若无数据交换,排序结束,如果存在执行步骤1
选择排序
实现
- 将整个数组作为排序区间
- 将排序区间的最小值(最大值)与起始元素交换
- 将排序段的起始位置后移一位,循环步骤2
插入排序
实现
- 将数组的[1:end]作为排序区间
- 将起始元素放在前段已排序数组的合理位置(大于前一个元素,小于后一个元素)。
- 将排序区间的起始位置后移一位,执行步骤2
优化
针对步骤2,将交换操作换为赋值操作
- 未优化前 当当前元素小于前一元素时,两者交换
- 优化后 保存当前元素,将大于该元素的区间元素整体后移,将当前元素保存至区间的首位
归并排序
实现
- 将数组分为两段
- 对每段执行归并排序
- 对两段执行归并操作
优化
- 当两部分已经有序则无须merge。
- 当排序数组较小时,则使用插入排序进行排序。
快速排序
实现
- 起始元素作为分界元素v
- 认为剩下所有的元素均大于v,即[1,end]为大于v元素区间,从第二个元素向后扫描,当发现有小于v的元素,则将其与大于v元素区间的第一位进行交换
- 扫描完毕之后将,元素v即起始位置元素与小于v元素区间的首位进行交换。
- 对小于v元素区间和大于v元素区间分别执行步骤1
优化
- 针对近乎有序的数组:
- 随机取出一个元素v作为分界元素,与起始元素交换位置,当然不影响通常状态下的排序速度
- 认为
<v
,>v
区间均为空,从两端向中间搜索,将两端不符合条件的元素交换。
- 针对有较多重复键值的数组:
- 采取
quickSort 3 ways
,将区间分为三部分,即<v
,==v
和>v
。 认为三个区间均为空。 - 从两端向中间搜索,将小于v的元素与等于v的区间第一位元素交换,将大于v的元素,与大于v区间的前一位元素交换。
- 其中对于近乎有序且有较多重复键值的数组,与大于v区间的前一位元素交换前,先判断是否大于v,若大于v则,将区间起始位前移。
- 采取
- 在数组元素较少时选择插入排序进行排序
排序算法应用
逆序对
- 暴力遍历(两两作比) 复杂度
- 归并排序(排序过程中记录逆序对即可) 复杂度
取数组的第n大的元素
- 排序
- 快速排序(仅对第n位所在区间分析) 复杂度
复杂度 = n + n/2 + n/4 + … + 1 = 2n
堆排序 Heap Sort
实现
- 对数据进行堆化
- 从堆中依次取出最大(小)堆顶元素,直至为空
排序算法对比
平均复杂度 | 原地排序 | 额外空间 | 稳定排序 | |
---|---|---|---|---|
插入排序 | O(n^2) | ✔ | O() | ✔ |
归并排序 | O(nlogn) | O(1) | ✘ | |
快速排序 | O(nlogn) | ✔ | O(nlogn) | ✘ |
堆排序 | O(nlogn) | ✔ | O(1) | ✘ |