题目描述
思路解析动画文字版
记住两个角色:i 是当前趟要填的位置(未排序区的开头),min 是这一趟扫到目前为止最小值所在的下标。
一开始整个数组都属于未排序区(右段),左边的已排序区还是空的。我们一趟一趟地把最小值挑到左边。
第 1 趟:要填的位置是下标 0。先假设它自己就是未排序区的最小值,min = 0(值 5),再往右逐个比对。
比下标 1 的值 2 和当前最小 5:2 更小,把 min 改记到下标 1。
比下标 2 的值 4 和当前最小 2:4 不比 2 小,min 保持不变。
比下标 3 的值 1 和当前最小 2:1 更小,把 min 改记到下标 3。
比下标 4 的值 3 和当前最小 1:3 不比 1 小,min 保持不变。
本趟扫完,最小值在下标 3。把它和下标 0 交换,于是下标 0 被填上正确的值 1,已排序区往右扩了一格。
第 2 趟:要填的位置是下标 1。先假设它自己就是未排序区的最小值,min = 1(值 2),再往右逐个比对。
比下标 2 的值 4 和当前最小 2:4 不比 2 小,min 保持不变。
比下标 3 的值 5 和当前最小 2:5 不比 2 小,min 保持不变。
比下标 4 的值 3 和当前最小 2:3 不比 2 小,min 保持不变。
本趟最小值正好就在下标 1,不用交换。下标 1 已经是正确的值 2,已排序区往右扩一格。
第 3 趟:要填的位置是下标 2。先假设它自己就是未排序区的最小值,min = 2(值 4),再往右逐个比对。
比下标 3 的值 5 和当前最小 4:5 不比 4 小,min 保持不变。
比下标 4 的值 3 和当前最小 4:3 更小,把 min 改记到下标 4。
本趟扫完,最小值在下标 4。把它和下标 2 交换,于是下标 2 被填上正确的值 3,已排序区往右扩了一格。
第 4 趟:要填的位置是下标 3。先假设它自己就是未排序区的最小值,min = 3(值 5),再往右逐个比对。
比下标 4 的值 4 和当前最小 5:4 更小,把 min 改记到下标 4。
本趟扫完,最小值在下标 4。把它和下标 3 交换,于是下标 3 被填上正确的值 4,已排序区往右扩了一格。
最后一格(下标 4)自然就是剩下唯一的数,无需再比。整个数组从小到大排好了:1,2,3,4,5。
三个高频追问:与冒泡的区别、稳定性、以及为什么对有序数组也没有加速。
参考代码
def selection_sort(nums): n = len(nums) for i in range(n - 1): # i 是本趟要填的位置 min_i = i # 先假设 i 处最小 for j in range(i + 1, n): if nums[j] < nums[min_i]: min_i = j # 记下更小的下标 nums[i], nums[min_i] = nums[min_i], nums[i] # 换到最前 return nums复杂度
- 时间:O(n²),两层循环,比较次数约 n(n-1)/2,和数据是否有序无关
- 空间:O(1),只用 min_i 一个下标和一次交换的临时变量,原地排序
- 交换:O(n),每趟最多换一次,总交换次数最多 n-1,是它相对冒泡的优点
易错点
面试追问把动画讲成自己的话
追问选择排序和冒泡排序最大的区别是什么?
追问选择排序是稳定排序吗?
追问它的时间复杂度会因为数组本来有序而变好吗?
这道题到这就讲完了。动画和文字是同一套思路——别光看,关掉页面自己默写一遍。然后顺着主线继续:
插入排序
简单 · 沿着 排序套路 继续往下推进
把这道题真正学会,再走
图解算法年卡 ¥99 /年
- ✓本题每步动画的吴师兄语音讲解(全站陆续覆盖)
- ✓小欧带 8 步通关训练——追问到不看答案也能写对、能 30 秒讲给面试官听
- ✓学习报告,记录每道题的掌握程度
76k+ GitHub Star · 吴师兄开源图解算法,几十万开发者在看的算法讲解
想成体系刷透这类套路?去图解算法专题