6-8 分钟
拆解选择排序
核心重难点
算法思想 · 双层循环逻辑 · 升降序切换
最基础的排序算法,零基础也能轻松学懂
同学们大家好!选择排序是最基础的排序算法。在要排序的一组数中,我们假设第一个元素是最小值,然后依次与后面的元素作比较,如果有更小的值,就交换位置。今天这节微课,我们就逐层拆解选择排序的所有重点和难点。
Contents · 本课内容
4 大模块 · 全流程覆盖
从原理到实训,让你独立看懂、理解通透、会写会改代码
01
核心算法思想 + 双层循环逻辑
假设最小值、依次比较、找索引再交换
02
代码编写 + 升降序切换
只改一个判断条件,一键切换升降序
03
实训案例:5 个数递增排序
数组 [5,4,6,3,1] 打擂法排序全流程
04
VS2010 示范操作 + 完整代码
新建项目到运行调试,手把手实操
本节课我们将逐一攻克以上3大重点和3大难点,循序渐进,零基础也能轻松学懂选择排序。
重点突破 · 01
选择排序
核心算法思想
假设第一个是最小值,依次与后面比较,找到更小值则交换
首先我们掌握本节课第一个核心重点:选择排序的算法思想。选择排序是最基础的排序算法,核心思路是每一轮从待排序的元素中选出最小值,放到已排序序列的末尾。
核心原理 · 假设最小值 + 依次比较 + 交换
以数组 [5, 4, 6, 3, 1] 为例
观察完整排序过程:每轮找出最小值,交换到正确位置
当前轮次:-
当前步骤:-
已排序元素:0 个
我们以无序数组5、4、6、3、1举例。第一轮:假设第一个数5是最小值,依次比较后面的元素。找到1是最小值,将其与第一个位置交换,数组变成1、4、6、3、5。第二轮从4开始,找到3为最小值,交换后数组变为1、3、6、4、5。以此类推,4轮后完成排序。
难点突破 · 01
双层循环
执行逻辑
外层定位置选最小值,内层遍历找更小——与冒泡排序的关键区别
理解了算法思想,我们攻克本节课最大的难点:双层循环的执行逻辑。选择排序与冒泡排序不同,它的内层循环不是相邻交换,而是找到最小值的索引,一轮只交换一次。
难点突破 · 内外循环各司其职
外层定位置,内层找最小
选择排序核心口诀:外层管位置,内层找最小
外层 for 循环
📍 控制当前位置与轮数
- 确定每轮"待填入最小值"的位置
- 有 n 个元素,最多需要 n-1 轮
- 每轮开始时,假设当前位置是最小值
- 每走一次 = 确定一个最终位置
for (int i = 0; i < n-1; i++)
内层 for 循环
🔍 遍历后续元素找最小值
- 从 i+1 位置开始向后遍历
- 遇到更小值就更新最小值索引
- 只记录索引,不直接交换
- 一轮结束后,只做一次交换
for (int j = i+1; j < n; j++)
💡 核心口诀:外层管位置,内层找最小,一轮只换一次
选择排序 vs 冒泡排序
冒泡每轮多次交换相邻元素;选择每轮只交换一次(最小值到位)
⚠️ 最易混淆点
内层循环比较的是 arr[j] 和 arr[minIndex],不是相邻元素!
首先是外层for循环:它的核心作用是确定每轮"待填入最小值"的位置,从第0个位置开始,逐轮后移。然后是内层for循环:从i+1位置开始向后遍历,遇到更小值就更新最小值索引,但并不立即交换,而是一轮结束后只做一次交换。大家记住:选择排序的内层循环找的是最小值的索引,不是直接交换,这是与冒泡排序最大的区别。
难点突破 · 02
每轮内层循环起始位置递增
已排序部分不再参与比较,内层从 i+1 开始
| 轮次(外层 i) | 当前位置 | 内层起始位置 | 比较次数 | 每轮结束时 |
| 第 1 轮(i = 0) | arr[0] | j = 1 | 3 次 | 最小值放到 arr[0] |
| 第 2 轮(i = 1) | arr[1] | j = 2 | 2 次 | 次小值放到 arr[1] |
| 第 3 轮(i = 2) | arr[2] | j = 3 | 1 次 | 第三小值放到 arr[2] |
| 第 i 轮 | arr[i] | j = i + 1 | n - 1 - i 次 | 第 i 小值就位 |
❌ 常见错误
内层循环从 0 开始,导致已排序部分被重复比较,浪费性能甚至破坏已排序结果
✅ 正确做法
内层循环从 i+1 开始,已排序的前 i 个元素不再参与比较
接下来我们突破第二个难点:每轮内层循环的起始位置是递增的。第一轮从位置1开始比较,第二轮从位置2开始,第三轮从位置3开始。因为每轮结束后,前面已经排好序的元素不需要再参与比较了。所以内层循环的起始位置是 i+1,这就是递减规律的核心。
重点突破 · 02 + 难点突破 · 03
C# 代码
编写与调试
从升序到降序,只需修改一个判断条件
最后我们整合所有逻辑,完成本节课最后一个重点和最难的难点:代码编写调试,以及升序、降序的自由切换。
C# 实现 · 标准升序排序
完整代码:从小到大排序
双层 for 循环,内层找最小值索引,一轮只交换一次
// 选择排序:升序(从小到大)
int[] arr = { 3, 1, 4, 2 };
int n = arr.Length;
// 外层循环:控制当前位置,共 n-1 轮
for (int i = 0; i < n - 1; i++)
{
// 假设当前位置是最小值
int minIndex = i;
// 内层循环:从 i+1 开始找更小值
for (int j = i + 1; j < n; j++)
{
// 判断:找到更小的值?更新最小值索引
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
}
// 一轮结束后:交换当前位置与最小值
if (minIndex != i)
{
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
// 输出结果:[1, 2, 3, 4]
⚠️ 易错点 1:内层比较对象
比较的是 arr[j] 和 arr[minIndex],不是 arr[j] 和 arr[j-1]
⚠️ 易错点 2:交换需临时变量
借助 temp 变量交换 arr[i] 和 arr[minIndex],不能直接覆盖
首先是标准升序排序代码:外层循环控制当前位置,每轮假设当前位置是最小值,用minIndex记录。内层循环从i+1开始遍历,如果找到比arr[minIndex]更小的值,就更新minIndex。一轮结束后,如果minIndex不等于i,就交换arr[i]和arr[minIndex]。最终实现从小到大排序。
核心技巧 · 一键切换升降序
只改一个判断条件,无需改动其他代码
升序找最小值放前面,降序找最大值放前面
📈 升序(从小到大)
找最小值放到当前位置
if (arr[j] < arr[minIndex])
{
minIndex = j;
}
// 一轮结束后交换
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
结果:[1, 2, 3, 4]
⇄
📉 降序(从大到小)
找最大值放到当前位置
if (arr[j] > arr[minIndex])
{
minIndex = j;
}
// 一轮结束后交换
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
结果:[4, 3, 2, 1]
🎯 核心记忆:升序用 < 找最小,降序用 > 找最大,只改这一个符号!
想要实现降序排序,大家记住核心技巧,只需要把判断条件从"小于"改为"大于"即可。升序时找最小值放到前面,降序时找最大值放到前面。循环结构、交换代码完全不变,只改一个符号,就能一键切换升降序。
动手实操 · 实训任务
实训案例
5 个数递增排序
已知数组中有 5 个数:5、4、6、3、1,用选择法按递增顺序排序
接下来进入动手实操环节。已知数组中有5个数:5、4、6、3、1,我们用选择法按递增顺序排序。这是中职C#程序设计课程的标准实训任务。
实训分析 · 打擂法找最小值
选择法排序 = 打擂法 + 重复 n-1 遍
选择法是最简单且易于理解的排序算法
🥊
什么是"打擂法"?
就像擂台比赛:先派一个人当"擂主"(假设最小值),后面的数依次上台挑战。挑战者更小就替换擂主,最后留在台上的就是真正的最小值。
①
第 1 轮:找最小数
用打擂法从 n 个数中找出最小数的位置,将最小数与第 1 个数交换位置。
②
第 2 轮:找次小数
除第 1 个数外,其余 n-1 个数再按打擂法找出次小数,让其与第 2 个数交换。
③
重复 n-1 遍
重复以上步骤 n-1 遍,最后生成递增序列。递减排序则每次找最大数即可。
🔑
双重循环结构
内循环找最小数并记下位置;外循环共执行 n-1 次,每次找到一个最小数。
选择法排序是最简单且易于理解的算法。假定数组中有n个数,要求按递增的次序排序。第一步:用打擂法从n个数中找出最小数的位置,然后将最小数与第1个数交换位置。第二步:除第1个数外,其余n-1个数再按同样方法找出次小数的位置,让其与第2个数交换位置。第三步:重复步骤n-1遍。由此可见,数组排序必须用双重循环:内循环找最小数并记下位置,外循环共执行n-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 个数 [5,4,6,3,1] 选择排序
在 Main 方法中输入以下代码
static void Main(string[] args)
{
int[] a = new int[5] { 5, 4, 6, 3, 1 };
int min, i, j, k, m, temp;
Console.Write("原始数列:");
for (i = 0; i <= 4; i++)
{
Console.Write(a[i] + " ");
}
// 选择排序法
for (j = 0; j <= 3; j++)
{
min = j; // 假设第j个数最小,记录下它的位置
for (k = j + 1; k <= 4; k++)
{
// 如果找到更小的数,记录下它的位置
if (a[k] < a[min])
{
min = k;
}
}
// 将假设的小数与找到的小数交换位置
temp = a[j];
a[j] = a[min];
a[min] = temp;
}
Console.WriteLine();
Console.Write("选择法排序后的结果为:");
// 输出排序结果
for (m = 0; m <= 4; m++)
{
Console.Write("{0} ", a[m]);
}
Console.ReadKey();
}
> 原始数列:5 4 6 3 1
> 选择法排序后的结果为:1 3 4 5 6
这是完整的实训代码。定义数组a有5个元素5、4、6、3、1。先输出原始数列。然后使用选择排序:外层循环j从0到3,共4轮。每轮先用min记录当前位置j,内层循环k从j+1到4,如果a[k]小于a[min],就更新min为k。内层循环结束后,交换a[j]和a[min]。最后输出排序结果:1 3 4 5 6。注意变量命名使用了i、j、k、m、temp,这是中职教材的标准写法。
Summary · 核心口诀总结
五大要点,一次吃透选择排序
从原理到实训,截图保存随时复习
1
核心思想
假设最小值、依次比较、找到更小则更新索引,一轮结束后交换一次
2
双层循环分工
外层管位置(n-1轮),内层从 i+1 遍历找最小值索引
3
递减规律
内层从 i+1 开始,已排序元素不再参与比较,每轮比较次数递减
4
升降序切换
升序用 < 找最小值,降序用 > 找最大值,只改一个符号
5
实训落地:打擂法 + VS2010 实操
5 个数 [5,4,6,3,1] 用打擂法 4 轮排序完成,结果 [1,3,4,5,6]。在 VS2010 中新建控制台应用程序,输入代码后按 F5 运行即可看到结果
最后我们快速复盘本节课所有重难点。第一,选择排序核心:假设最小值、依次比较、一轮交换一次;第二,双层循环分工:外层管位置,内层找最小;第三,递减规律:内层从i+1开始,每轮比较次数递减;第四,升降序切换:升序用小于找最小,降序用大于找最大,只改一个符号。
🎓
微课结束
恭喜你完成了选择排序重难点专项学习!
课后请独立完成一遍代码编写,巩固所学。
中职 C# 程序设计
完全贴合课标要求
课前预习 · 课后复盘
同学们,本节微课到此结束。掌握以上四点,大家就能完全吃透选择排序的所有重难点,独立完成代码编写和优化。课后请务必自己动手写一遍代码,实践是最好的老师!