图解题库 / 排序 · 选择

选择排序

简单 含交互动画

学完这道你应该能: 说清它为什么用「选择」,而不是死记步骤; 合上页面,自己默写出核心代码; 用 30 秒把思路讲清楚。

题目描述

把数组分成"已排序"和"未排序"两段。每趟在未排序段里找最小值,和未排序段的第一个交换。

输入 = [5, 2, 4, 1, 3]
输出 = [1, 2, 3, 4, 5]

思路解析

第 i 趟:从下标 i 到末尾扫一遍,记下最小值的位置,然后把它和 i 位置交换。这样下标 i 就确定了最终该放的数。

第 1 趟 · 扫描找最小:在整个数组里扫一遍,找到最小值 1(在下标 3)。

最小的 1 换到最前:把 1 和下标 0 交换,1 归位。已排序区 = [1]。

第 2 趟 · 在 [2,4,5,3] 找最小:在剩下的未排序区找最小 = 2(已在下标 1),不用换。已排序区扩到 [1,2]。

第 3 趟 · 最小 3 换上来:未排序区 [4,5,3] 的最小是 3,和下标 2 交换。3 归位

第 4 趟 · 4 换到位:最后未排序区 [5,4] 的最小是 4,交换归位。剩下的 5 自动到位,全部有序

选择排序的思路是“为每个位置选对的数”,冒泡是“让对的数浮上去”。同为 O(n²),但选择的交换更省。

参考代码(Python)

Python
1n = len(nums)
2for i in range(n - 1):
3    min_idx = i                        # 假设当前位最小
4    for j in range(i + 1, n):         # 在未排序区找更小
5        if nums[j] < nums[min_idx]:
6            min_idx = j
7    nums[i], nums[min_idx] = nums[min_idx], nums[i]   # 换到位

复杂度分析

  • 时间复杂度:O(n²) —— 比较次数固定,与初始无关
  • 空间复杂度:O(1) —— 原地

套路模板

记住骨架:外层定位置、内层找最小下标、末尾一次交换。和“堆排序”思想相通——堆排是用堆更快地“选最大”。

Python
1for i in range(n - 1):
2    m = i
3    for j in range(i+1, n):
4        if a[j] < a[m]: m = j           # 记最小下标
5    a[i], a[m] = a[m], a[i]            # 一趟一次交换

易错点

  • 边找边交换 → ✅ 找到最小下标后再换一次(边找边换会多做无用交换、还可能破坏稳定)
  • 内层从 i 开始 → ✅ 从 i+1 开始找(i 本身就是待放入的位置)

以上文字与上方动画完全同一思路:先看动画建立直觉 → 读文字巩固 → 关掉页面自己默写一遍代码,能写出来才算真的掌握

下一题 →插入排序 ← 返回题库