插入排序

1004 字
5 分钟
插入排序

插入排序#

插入类排序的核心思想:将元素插入到已排序序列的合适位置。代表算法有直接插入排序折半插入排序希尔排序

直接插入排序#

核心思想#

  • 将待排序序列分为已排序未排序两部分,初始时已排序部分只有第一个元素
  • 每次从未排序部分取出第一个元素,在已排序部分中从后向前扫描,找到合适位置插入
  • 有序区不断扩大,直到全部元素有序

代码实现#

带哨兵的实现(⭐ 考研重点):

void InsertSort(int A[], int n) {
int i, j;
for (i = 2; i <= n; i++) {
if (A[i] < A[i - 1]) {
A[0] = A[i]; // A[0]作为哨兵
for (j = i - 1; A[0] < A[j]; j--)
A[j + 1] = A[j];
A[j + 1] = A[0];
}
}
}

哨兵的作用:免去内层循环每次判断 j >= 1 是否越界,简化边界条件。

复杂度#

指标说明
最好时间O(n)序列已有序,每趟只比较 1 次
最坏时间O(n²)序列逆序
平均时间O(n²)平均比较和移动次数约 n²/4
空间O(1)仅常数级辅助空间
稳定性稳定相等元素不交换

折半插入排序#

改进点#

折半查找替代顺序查找来定位插入位置,比较次数降为 O(log i),但移动次数不变

关键代码#

void BinaryInsertionSort(int a[], int n) {
int i, j, low, high, mid, temp;
for (i = 1; i < n; i++) {
temp = a[i];
low = 0; high = i - 1;
while (low <= high) {
mid = (low + high) / 2;
if (a[mid] > temp) high = mid - 1;
else low = mid + 1; // 相等时进入右半,保证稳定性
}
for (j = i - 1; j >= low; j--)
a[j + 1] = a[j];
a[low] = temp;
}
}

与直接插入的对比#

维度直接插入折半插入
比较次数最好 O(n),最坏 O(n²)总 O(n log n)
移动次数O(n²)O(n²)
总时间复杂度O(n²)O(n²)
稳定性稳定稳定

⚠️ 易错:折半插入只减少比较次数,不减少移动次数,时间复杂度仍为 O(n²)。

希尔排序#

核心思想#

  • 选定增量序列 d₁ > d₂ > … > dₖ = 1
  • 每趟按当前增量 dᵢ 将序列分组,对各组执行直接插入排序
  • 增量不断缩小,最后一趟 d=1 时对”几乎有序”的序列做插入排序

代码实现#

void ShellSort(int A[], int n) {
for (int d = n / 2; d >= 1; d /= 2) {
for (int i = d; i < n; i++) {
int temp = A[i];
int j = i - d;
while (j >= 0 && A[j] > temp) {
A[j + d] = A[j];
j -= d;
}
A[j + d] = temp;
}
}
}

增量序列#

序列公式最坏时间
Shell 原始dᵢ = n/2ⁱO(n²)
Hibbarddᵢ = 2ⁱ - 1O(n^1.5)
Knuthdᵢ = (3ⁱ - 1)/2O(n^1.5)

考试默认使用 Shell 原始序列(d = n/2, n/4, …, 1),最后一个增量必须为 1。

复杂度#

指标
最坏时间O(n²)(Shell 原始序列)
平均时间~O(n^1.3)
空间O(1)
稳定性不稳定(相同元素可能分到不同组)
适用性仅限顺序表(需随机访问)

⚠️ 易错:希尔排序不稳定,相同元素可能分到不同组中,各组独立排序后相对顺序可能改变。

考研高频考点#

  • ⭐ 给定序列写出每趟直接插入/希尔排序的结果(选择题/填空题)
  • ⭐ 哨兵的作用及带哨兵代码的手写(代码题)
  • ⭐ 希尔排序与直接插入排序的关系与对比
  • ⭐ 折半插入排序的比较次数与初始序列无关(仅取决于 n)
  • ⭐ 希尔排序不能用于链表(需要随机访问)
  • 直接插入在基本有序序列上的时间复杂度 O(n)(408 经典选择题)

关联页面#

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

插入排序
https://lingluoa.icu/posts/sorting-insertion/
作者
lingluoa
发布于
2026-07-07
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
lingluoa
Hello, I'm lingluoa.
公告
欢迎来到我的博客!不定期更新中。
文章目录
标签
站点统计
文章
53
分类
9
标签
75
总字数
175,771
运行时长
0
最后活动
0 天前
站点信息
构建平台
ESA Pages
博客版本
Firefly v6.15.6
文章许可
CC BY-NC-SA 4.0