排序算法
1.选择排序
每次找出第 i 小的元素(也就是 a[i] ~ a[n] 中最小的元素),然后将这个元素与数组上第 i 个位置上的元素互换。
时间复杂度:$O(n^2)$
代码:
1 | void ssort(int *a, int n) |
2.冒泡排序
依次检查两两相邻的元素,如果满足给定的排序条件,就将相邻的两个元素交换。
时间复杂度:$O(n^2)$
代码:
1 | void ssort(int *a, int n) |
3.桶排序
桶排序的步骤如下:
- 设置一定大小的数组作为空桶
- 遍历序列,将数字放进对应桶中
- 遍历桶,将非空桶放回原序列中
时间复杂度:$O(n)$
事实桶排序的应用要比这丰富的多。待补充。
4.快速排序
快速排序的步骤如下:
- 设置一个分界点 x
- 将原序列分成 ≤x 和 ≥x 两个序列
- 递归处理
时间复杂度:$O(nlogn)$
代码:
1 | void qsort(int *q, int l, int r) |
要解释一下的是,中间对于序列划分的操作,实际上是建立了双指针:当 i 指针前进到一个大于 x ,且 j 指针前进到一个小于 x 的位置时,就将 i 指针和 j 指针对换。这样就保证了其满足过程二中的性质。
值得一提的是,这种写法要比某谷上随机化+去重后的代码跑的还快,而且并未使用新的空间,可以说是一种非常优秀的写法。
5.归并排序
归并排序的步骤如下:
- 设置中点 x,将原序列均分成前后两个序列
- 对前后两个序列分别递归,排序
- 将两个序列合并(想想两副洗好的扑克牌)
时间复杂度:$O(nlogn)$
代码:
1 | void msort(int *q, int l, int r) |
6.堆排序
用堆来存储序列,每次将堆顶元素(最小值)拿出,然后维护。
时间复杂度:$O(nlogn)$
代码参考数据结构堆即可。