6-8 分钟
拆解插入排序
核心重难点
排序区与未排序区 · 从后往前比较 · 元素后移插入
像整理扑克牌一样直观的排序算法
同学们大家好!插入排序是一种非常直观的排序算法。排序开始前,我们设想有排序区和未排序区两个区域,先将第一个元素看作在排序区,其他元素在未排序区。每次从未排序区取出第一个元素,和排序区中的元素从后往前比较,找到合适的位置插入。今天这节微课,我们就逐层拆解插入排序的所有重点和难点。
Contents · 本课内容
4 大模块 · 全流程覆盖
从原理到实训,让你独立看懂、理解通透、会写会改代码
01
核心算法思想 + 双层循环逻辑
排序区/未排序区、从后往前比较、元素后移插入
02
代码编写 + 升降序切换
只改一个判断条件,一键切换升降序
03
实训案例:5 个数递增排序
数组 [4,5,3,1,2] 插入法排序全流程
04
VS2010 示范操作 + 完整代码
新建项目到运行调试,手把手实操
本节课我们将逐一攻克4大模块:核心算法思想、代码编写与升降序切换、实训案例、以及VS2010示范操作。循序渐进,零基础也能轻松学懂插入排序。
重点突破 · 01
插入排序
核心算法思想
排序区 + 未排序区,从后往前比较,元素后移腾位再插入
首先我们掌握本节课第一个核心重点:插入排序的算法思想。插入排序的核心思路是将一个数据插入到已排好序的有序数列中,从而得到一个新的、数据量增1的有序数列。
核心原理 · 取出 → 比较 → 后移 → 插入
以数组 [4, 5, 3, 1, 2] 为例
观察完整排序过程:每轮取出未排序区第一个元素,插入到排序区正确位置
升序排序 · 绿色=已排序区 · 灰色=未排序区 · 橙色=当前插入元素
当前轮次:-
当前步骤:-
已排序元素:1 个
我们以无序数组4、5、3、1、2举例。初始时,第一个元素4在排序区,其余在未排序区。第1轮取出5,与4比较,5大于4不用移动,直接留在原位。第2轮取出3,与5比较,3小于5,5后移;再与4比较,3小于4,4后移;3插入到最前面。以此类推,4轮后完成排序。
难点突破 · 01
双层循环
执行逻辑
外层取元素,内层从后往前比较后移——与选择排序的关键区别
理解了算法思想,我们攻克本节课最大的难点:双层循环的执行逻辑。插入排序与选择排序不同,它的内层循环是从后往前遍历排序区,一边比较一边后移元素,找到位置后插入。
难点突破 · 内外循环各司其职
外层取元素,内层比较后移
插入排序核心口诀:取出、比较、后移、插入
外层 for 循环
📤 从未排序区取出元素
- 从第 2 个元素(索引1)开始
- 有 n 个元素,共执行 n-1 轮
- 每轮取出一个待插入元素存入 temp
- 每走一次 = 排序区增加一个元素
for (int j = 1; j < n; j++)
内层 for 循环
🔍 从后往前比较 + 后移
- 从 j-1 位置开始向前遍历
- 若 temp < a[k],则 a[k] 后移一位
- 若 temp ≥ a[k],则 插入到 k+1 位置
- 比到最前面(k=0)则插入到首位
for (int k = j-1; k >= 0; k--)
💡 核心口诀:外层取元素存temp,内层从后往前比较,大的后移腾位置,找到位置插入temp
插入排序 vs 选择排序
选择排序每轮找最小值交换;插入排序每轮取出元素,比较后移再插入
⚠️ 最易混淆点
内层循环是从后往前(k 递减),不是从前往后!元素是后移不是前移!
首先是外层for循环:从第2个元素开始,每次取出一个待插入元素存入temp变量。然后是内层for循环:从j-1位置开始从后往前遍历排序区,如果temp小于当前比较的元素,就把该元素后移一位;如果temp大于等于当前元素,就把temp插入到该元素后面。大家记住:内层循环是从后往前的,元素是往后移动的,这是与选择排序最大的区别。
难点突破 · 02
每轮排序区扩大,比较方向从后往前
排序区逐轮增长,内层从 j-1 向前比较到 0
| 轮次(外层 j) | 取出元素 | 排序区范围 | 内层比较方向 | 每轮结束时 |
| 第 1 轮(j = 1) | a[1] = 5 | a[0] ~ a[0] | k = 0 → 0 | 排序区:[4, 5] |
| 第 2 轮(j = 2) | a[2] = 3 | a[0] ~ a[1] | k = 1 → 0 | 排序区:[3, 4, 5] |
| 第 3 轮(j = 3) | a[3] = 1 | a[0] ~ a[2] | k = 2 → 0 | 排序区:[1, 3, 4, 5] |
| 第 4 轮(j = 4) | a[4] = 2 | a[0] ~ a[3] | k = 3 → 0 | 排序区:[1, 2, 3, 4, 5] |
| 第 j 轮 | temp = a[j] | a[0] ~ a[j-1] | k = j-1 → 0 | 排序区增加 1 个元素 |
❌ 常见错误
内层循环从前往后遍历,导致元素被错误覆盖;或忘记后移直接插入
✅ 正确做法
内层从 j-1 向前到 0,先比较再后移,最后插入 temp 到空出的位置
接下来我们突破第二个难点:每轮排序区的范围是逐步扩大的。第1轮排序区只有1个元素,第2轮有2个,以此类推。内层循环从j-1位置开始向前比较到0位置。注意比较方向是从后往前的,元素是往后移动的,这点和冒泡排序、选择排序都不同。
重点突破 · 02 + 难点突破 · 03
C# 代码
编写与调试
从升序到降序,只需修改一个判断条件
最后我们整合所有逻辑,完成本节课最后一个重点和最难的难点:代码编写调试,以及升序、降序的自由切换。
C# 实现 · 标准升序排序
完整代码:从小到大排序
双层 for 循环,temp 暂存取出元素,从后往前比较后移
// 插入排序:升序(从小到大)
int[] arr = { 4, 5, 3, 1, 2 };
int n = arr.Length;
// 外层循环:从第2个元素开始,共 n-1 轮
for (int j = 1; j < n; j++)
{
// 取出待插入元素,存入 temp
int temp = arr[j];
int k = j - 1;
// 内层循环:从后往前比较,大的元素后移
while (k >= 0 && arr[k] > temp)
{
arr[k + 1] = arr[k]; // 元素后移一位
k--;
}
// 找到位置,插入 temp
arr[k + 1] = temp;
}
// 输出结果:[1, 2, 3, 4, 5]
⚠️ 易错点 1:必须用 temp 暂存
取出 arr[j] 后必须先存入 temp,否则后移时会覆盖丢失
⚠️ 易错点 2:插入位置是 k+1
循环结束后 k 已自减,插入位置是 k+1,不是 k
首先是标准升序排序代码:外层循环从第2个元素开始,每轮取出arr[j]存入temp。内层用while循环从j-1位置往前遍历,只要arr[k]大于temp,就把arr[k]后移一位,k继续减1。循环结束后,把temp插入到k+1位置。最终实现从小到大排序。
核心技巧 · 一键切换升降序
只改一个判断条件,无需改动其他代码
升序大的后移,降序小的后移
📈 升序(从小到大)
大于temp 的元素后移
int temp = arr[j];
int k = j - 1;
while (k >= 0 && arr[k] > temp)
{
arr[k + 1] = arr[k];
k--;
}
arr[k + 1] = temp;
结果:[1, 2, 3, 4, 5]
⇄
📉 降序(从大到小)
小于temp 的元素后移
int temp = arr[j];
int k = j - 1;
while (k >= 0 && arr[k] < temp)
{
arr[k + 1] = arr[k];
k--;
}
arr[k + 1] = temp;
结果:[5, 4, 3, 2, 1]
🎯 核心记忆:升序用 > 后移大值,降序用 < 后移小值,只改这一个符号!
想要实现降序排序,大家记住核心技巧,只需要把while条件中的"大于"改为"小于"即可。升序时大于temp的元素后移,降序时小于temp的元素后移。循环结构、后移和插入逻辑完全不变,只改一个符号,就能一键切换升降序。
动手实操 · 实训任务
实训案例
5 个数递增排序
已知数组中有 5 个数:4、5、3、1、2,用插入法按递增顺序排序
接下来进入动手实操环节。已知数组中有5个数:4、5、3、1、2,我们用插入法按递增顺序排序。这是中职C#程序设计课程的标准实训任务。
实训分析 · 有序数列 + 逐步插入
插入法 = 将数据插入有序数列
第一个元素看作有序序列,其余逐步插入合适位置
🃏
插入排序就像整理扑克牌
左手拿着已排好序的牌(排序区),右手从牌堆中取一张牌(未排序区),从右往左和左手的牌比较,找到合适位置后插进去。每插一张,左手的有序牌就多一张。
①
初始状态
第 1 个元素 4 看作有序序列(排序区),其余 4 个元素为未排序序列。
②
从头到尾扫描
依次扫描未排序序列的每个元素,将其插入有序序列的适当位置。
③
从后往前比较
取出的元素与排序区从后往前比较,大的后移腾位,找到位置后插入。
🔑
相等元素的处理
若待插入元素与排序区某元素相等,将待插入元素插入到相等元素的后面。
插入法排序是将一个数据插入到已排好序的有序数列中,从而得到一个新的、数据量增1的有序数列。若对一个无序序列使用插入排序,则可以将待排序序列的第一个元素看作有序序列,把第二个元素到最后一个元素看作未排序序列,然后从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。若待插入的元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素的后面。
示范操作 · 新建项目
在 Visual Studio 2010 中实操
从新建项目到代码编写,手把手跟着做
运行 Visual Studio 2010
启动 Microsoft Visual Studio 2010 开发环境VS2010
新建项目
选择菜单项「文件」→「新建」→「项目」,打开"新建项目"对话框
选择项目类型
选择「Visual C#」→「Windows」,在模板列表中选择「控制台应用程序」Console App
进入代码编辑
系统自动生成代码框架,在 static void Main(string[] args) 代码段中输入相应代码
编译运行
按 F5 或点击运行按钮,查看排序结果F5 运行
首先运行Microsoft Visual Studio 2010。然后选择菜单项"文件"-"新建"-"项目",打开"新建项目"对话框,选择"Visual C#"下的"Windows",在模板列表选择"控制台应用程序"。系统进入代码编辑环境后,将自动生成代码框架,在static void Main(string[] args)代码段中输入相应代码。
实训代码 · 完整实现
5 个数 [4,5,3,1,2] 插入排序
在 Main 方法中输入以下代码
static void Main(string[] args)
{
int[] a = { 4, 5, 3, 1, 2 };
int i, j, k, m, temp;
Console.WriteLine("原始数组:");
for (i = 0; i <= 4; i++)
{
Console.Write(a[i] + " ");
}
// 插入排序法
for (j = 1; j <= 4; j++)
{
temp = a[j]; // 取出待插入元素
for (k = j - 1; k >= 0; k--)
{
if (temp < a[k]) // 从后往前比较
{
a[k + 1] = a[k]; // 元素后移一位
}
else
{
a[k + 1] = temp; // 插入到正确位置
break; // 跳出内层循环
}
if (k == 0) // 比到最前面
{
a[k] = temp; // 插入到首位
}
}
}
Console.WriteLine();
Console.WriteLine("插入法排序后的结果为:");
// 输出排序结果
for (m = 0; m <= 4; m++)
{
Console.Write("{0} ", a[m]);
}
Console.ReadLine();
}
> 原始数组:
4 5 3 1 2
> 插入法排序后的结果为:
1 2 3 4 5
这是完整的实训代码。定义数组a有5个元素4、5、3、1、2。先输出原始数组。然后使用插入排序:外层循环j从1到4,共4轮。每轮先用temp保存a[j],内层循环k从j-1递减到0,如果temp小于a[k],就把a[k]后移到a[k+1];否则把temp插入到a[k+1]并跳出循环。如果k减到0,就把temp插入到a[0]。最后输出排序结果:1 2 3 4 5。注意这段代码使用了for循环加break的方式,是中职教材的标准写法。
Summary · 核心口诀总结
五大要点,一次吃透插入排序
从原理到实训,截图保存随时复习
1
核心思想
排序区 + 未排序区,取出未排序区第一个元素,从后往前比较插入
2
双层循环分工
外层取元素存temp(n-1轮),内层从 j-1 向前比较后移
3
比较方向与后移
从后往前比较,大的元素后移腾位置,找到位置后插入 temp
4
升降序切换
升序用 > 后移大值,降序用 < 后移小值,只改一个符号
5
实训落地:5 个数插入排序 + VS2010 实操
5 个数 [4,5,3,1,2] 用插入法 4 轮排序完成,结果 [1,2,3,4,5]。在 VS2010 中新建控制台应用程序,输入代码后按 F5 运行即可看到结果
最后我们快速复盘本节课所有重难点。第一,插入排序核心:排序区加未排序区,取出元素从后往前比较插入;第二,双层循环分工:外层取元素存temp,内层从j-1向前比较后移;第三,比较方向与后移:从后往前比较,大的后移腾位,插入temp;第四,升降序切换:升序用大于后移大值,降序用小于后移小值,只改一个符号;第五,实训落地:5个数用插入法4轮排序完成,结果1 2 3 4 5。
🎓
微课结束
恭喜你完成了插入排序重难点专项学习!
课后请独立完成一遍代码编写,巩固所学。
中职 C# 程序设计
完全贴合课标要求
课前预习 · 课后复盘
同学们,本节微课到此结束。掌握以上五点,大家就能完全吃透插入排序的所有重难点,独立完成代码编写和优化。课后请务必自己动手写一遍代码,实践是最好的老师!