选择排序的核心逻辑是每轮在未排序部分找最小值,与该部分首位置交换;外层循环n-1轮(i从0到n-2),内层j从i+1到n-1找极值,index_min须初始化为i。

选择排序的核心逻辑是什么
选择排序不是靠“交换相邻元素”来推进,而是每轮在未排序部分找最小(或最大)值,把它和未排序区间的第一个位置交换。C++ 数组本身不带排序方法,得手动写三重逻辑:外层控制轮数、内层找极值、末尾做一次交换。
关键点在于:index_min 必须初始化为当前轮起始下标,不能设成 0 或 -1;否则找极值会越界或漏比较。
用普通数组实现时怎么写循环边界
假设数组长度为 n,要排满 n 个元素,但最后一轮只剩一个数,无需再比——所以外层循环只需跑 n-1 轮,即 i 从 0 到 n-2(含)。
内层查找范围是 j 从 i+1 到 n-1(含),确保只在未排序部分里找最小值。
立即学习“C++免费学习笔记(深入)”;
常见错误:
- 外层写成
i → 最后一轮 <code>i == n-1时,内层j从n开始,直接越界访问 - 内层写成
j → 访问 <code>arr[n],这是越界读,可能触发 undefined behavior
swap 函数用 std::swap 还是手写交换
推荐直接用 std::swap,它对基本类型是高效汇编级交换,对自定义类型也支持 ADL 和移动语义。手写 temp = a; a = b; b = temp; 在 C++11 后反而可能错过优化。
注意包含头文件:#include <utility>(C++11 起 std::swap 在此头文件);旧代码若用 #include <algorithm> 也能用,但非标准保证。
示例关键片段:
for (int i = 0; i < n - 1; ++i) {
int index_min = i;
for (int j = i + 1; j < n; ++j) {
if (arr[j] < arr[index_min]) {
index_min = j;
}
}
std::swap(arr[i], arr[index_min]);
}
数组传参时为什么不能直接写 int arr[]
函数参数写 void sort(int arr[]) 看似接收数组,实际等价于 void sort(int* arr) —— 数组退化为指针,长度信息丢失。没长度就无法控制循环边界,必然出错。
实操建议分两种情况:
- 已知固定大小(如
int a[10]):用模板推导长度,template<size_t N> void sort(int (&arr)[N]) - 通用场景:必须额外传长度,
void sort(int arr[], int n)或更现代的void sort(int* arr, size_t n)
漏传长度、或把 sizeof(arr) 当数组大小用,是新手最常踩的坑——此时得到的是指针大小(通常 4 或 8),不是元素个数。


















