排序算法概述
排序的本质是重新排列表中的元素,使表中的元素满足按关键字有序的过程。输入 n 个记录 R1, R2,…, Rn,对应的关键字为 k1, k2,…, kn。输出则是输入序列的一个重排,使得有 k1ʹ≤k2ʹ≤…≤knʹ(也可递减)。
评价指标
评价一个排序算法的好坏,主要看三个维度:
- 时间复杂度:算法执行所需的时间。
- 空间复杂度:算法执行所需的额外内存空间。
- 稳定性:若待排序表中有两个元素 Ri 和 Rj,其对应的关键字相同(keyi = keyj),且在排序前 Ri 在 Rj 的前面,若使用某一排序算法排序后,Ri 仍然在 Rj 的前面,则称这个排序算法是稳定的,否则是不稳定的。
分类
- 内部排序:数据都在内存中,关注如何使算法时、空复杂度更低。
- 外部排序:数据太多,无法全部放入内存,还要关注如何使读/写磁盘次数更少。
插入类排序
直接插入排序
每次将一个待排序的记录按其关键字大小插入到前面已排好序的子序列中,直到全部记录插入完成。
void InsertSort(int A[], int n) {
int i, j, temp;
for(i=1; i<n; i++) { // 将各元素插入已排好序的序列中
if(A[i] < A[i-1]) { // 若 A[i] 关键字小于前驱
temp = A[i]; // 用 temp 暂存 A[i]
for(j=i-1; j>=0 && A[j]>temp; --j) { // 检查所有前面已排好序的元素
A[j+1] = A[j]; // 所有大于 temp 的元素都向后挪位
}
A[j+1] = temp; // 复制到插入位置
}
}
}
带哨兵的直接插入排序:引入哨兵优化边界判断,避免每次循环都检查下标是否越界。
void InsertSort(int A[], int n) {
int i, j;
for(i=2; i<=n; i++) { // 依次将 A[2]~A[n] 插入到前面已排序序列
(A[i] < A[i]) {
A[] = A[i];
(j=i; A[]<A[j]; --j) {
A[j+] = A[j];
}
A[j+] = A[];
}
}
}


