1. 先从生活例子开始理解
想象一下你要整理一副扑克牌,按照从小到大的顺序排列:
初始牌序:9, 105, 23, 19, 1
选择排序的思路就像这样:
找最小:在未排序部分中找到最小元素
记录位置:记录最小元素的索引,而不是直接交换
一次交换:每轮外层循环只进行一次交换
2. 用简单语言解释算法步骤
// 假设我们有这些数字:9, 105, 23, 19, 1
// 第1轮:找到最小的数字1,和第一个数字9交换
// 结果:1, 105, 23, 19, 9
// 第2轮:从剩下的数字中找到最小的9,和第二个数字105交换
// 结果:1, 9, 23, 19, 105
// 第3轮:从剩下的数字中找到最小的19,和第三个数字23交换
// 结果:1, 9, 19, 23, 105
// 第4轮:剩下的已经有序,不需要交换
// 最终结果:1, 9, 19, 23, 105
3. 基础代码演示(带详细注释)
using System;
class Program
{
static void Main()
{
// 我们要排序的数字数组
int[] numbers = { 9, 105, 23, 19, 1 };
Console.WriteLine("原始数组: " + string.Join(", ", numbers));
// 调用选择排序方法
SelectionSort(numbers);
Console.WriteLine("排序后数组: " + string.Join(", ", numbers));
}
static void SelectionSort(int[] arr)
{
// 数组长度
int n = arr.Length;
// 外层循环:控制排序的轮数
// 每轮确定一个最小元素的位置
for (int i = 0; i < n - 1; i++)
{
Console.WriteLine($"\n=== 第{i+1}轮开始 ===");
Console.WriteLine("当前数组: " + string.Join(", ", arr));
// 假设当前轮次的第一个元素是最小的
int minIndex = i;
Console.WriteLine($"假设位置{i}的数字{arr[i]}是最小的");
// 内层循环:在剩余元素中寻找真正的最小值
for (int j = i + 1; j < n; j++)
{
Console.WriteLine($" 比较: 当前最小值{arr[minIndex]} vs 位置{j}的数字{arr[j]}");
// 如果找到更小的数字,更新最小值的索引
if (arr[j] < arr[minIndex])
{
minIndex = j;
Console.WriteLine($" → 发现更小的数字! 新的最小值是位置{minIndex}的数字{arr[minIndex]}");
}
}
// 如果最小值不在当前位置,进行交换
if (minIndex != i)
{
Console.WriteLine($"交换位置{i}的数字{arr[i]}和位置{minIndex}的数字{arr[minIndex]}");
// 交换两个数字
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
Console.WriteLine($"交换后数组: " + string.Join(", ", arr));
}
else
{
Console.WriteLine("最小值已在正确位置,不需要交换");
}
}
}
}
4. 可视化执行过程
让我用表格展示每一轮的变化:
5. 关键概念解释
什么是"索引"(Index)?
int[] numbers = {9, 105, 23, 19, 1};
// 索引: 0 1 2 3 4
索引就是每个数字的位置编号
C#中索引从0开始计数
为什么用 minIndex
而不是直接比较值?
// 正确做法:记录最小值的索引
int minIndex = i;
if (arr[j] < arr[minIndex])
{
minIndex = j; // 只更新索引,不修改数组
}
// 错误做法:直接修改数组值
if (arr[j] < arr[minIndex])
{
arr[minIndex] = arr[j]; // 这样会丢失数据!
}
6. 练习:自己动手试试
任务1: 修改代码,实现从大到小排序
// 提示:只需要修改比较条件
// 把 < 改为 >
任务2: 对字符串数组按字母顺序排序
string[] words = {"banana", "apple", "cherry", "date"};
// 提示:字符串比较用 CompareTo 方法
7. 常见问题解答
Q: 为什么外层循环是 i < n-1
而不是 i < n
? A: 因为当确定了n-1个元素的位置后,最后一个元素自然就在正确位置了。
Q: 选择排序快吗? A: 对于小数据集可以,大数据集比较慢。时间复杂度是O(n²)。
Q: 什么时候用选择排序? A: 当数据量小,或者需要简单易懂的排序方法时。
8. 总结
选择排序的核心思想:
找:在未排序部分中找到最小元素
换:把最小元素放到已排序部分的末尾
重复:直到所有元素都排好序
记住这个口诀:"找最小,放前面,重复做,就排好!"