一、排序的基本概念(基础必懂)
✅ 排序定义
- 将一组无序数据按某种规则(如升序/降序)重新排列的过程。
✅ 分类方式
| 类型 |
特点 |
| 内部排序 |
所有数据放在内存中进行排序 → 如插入、交换、选择、归并、基数 |
| 外部排序 |
数据太大,不能全部放入内存,需借助磁盘 → 如多路归并排序 |
✅ 评价标准
| 指标 |
含义 |
| 时间复杂度 |
最好、最坏、平均情况下的比较次数 |
| 空间复杂度 |
额外存储空间大小 |
| 稳定性 |
相等元素的相对位置是否改变 → 稳定排序:相同元素顺序不变 |
💡 稳定性重要性:如学生成绩排序时,同分学生应保持原名次。
二、插入排序(Insertion Sort)
✅ (1)直接插入排序
📌 思想:
📌 步骤:
// 直接插入排序 A[]: 待排序数组 n: 元素个数
void InsertSort(ElemType A[], int n) {
for(int i = 2; i <= n; i++) { // 依次将A[2]~A[n]插入前面已排序序列
if(A[i] < A[i - 1]) { // 若A[i]关键码小于其前驱,将A[i]插入有序表
A[0] = A[i]; // 复制为哨兵,A[0]不存放元素
for(int j = i - 1; A[0] < A[j]; j--) { // 从后往前查找待插入位置
A[j + 1] = A[j]; // 向后挪位
}
A[j + 1] = A[0]; // 复制到插入位置
}
}
}
📌 时间复杂度:
📌 空间复杂度:
✅ 特点:
✅ (2)折半插入排序
📌 改进点:
📌 步骤:
// 折半插入排序 A[]: 待排序数组 n: 元素个数
void InsertSort(ElemType A[], int n) {
for(int i = 2; i <= n; i++) { //依次将A[2]~A[n]插入前面的已排序序列
A[0] = A[i]; //将A[i]暂存到A[0]
int low = 1; //设置折半查找的范围
int high = i - 1;
while(low <= high) { //折半查找(默认递增有序)
int mid = (low + high) / 2; //取中间点
if(A[0] > A[mid]) {
low = mid + 1; // 查找右子表
} else {
high = mid - 1; // 查找左半子表
}
}
for(int j = i - 1; j >= low; j--) {
A[j + 1] = A[j]; //统一后移元素,空出插入位置
}
A[low] = A[0]; //插入操作
}
}
📌 时间复杂度:
- 比较次数减少 →

- 移动次数仍为

✅ 特点:
✅ (3)希尔排序(Shell Sort)
📌 思想:
- 缩小增量排序:先对相距较远的元素进行插入排序,逐步缩小间隔
📌 增量序列(常见):
📌 时间复杂度:
✅ 特点: