ARTICLE · 1122430
开学考的这一题,值得一做!最坑的代码填空是这一句?
开学考的这一题,值得一做!最坑的代码填空是这一句?
最近,全省各地的开学考都在陆续进行中,其中七彩阳光开学考信息选择的最后一题,考到了一个排序算法的变形——双向选择排序,坑到了不少同学。 普通的选择排序大家都见过,每轮找一个最小值放到前面。但双向选择排序不一样——它每轮同时找最小值和最大值,分别放到左右两端。 今天这篇文章,朱老师就带大家把双向选择排序彻底拆解清楚,希望同学们看完之后能够有所收获~ 01 算法模型 双向选择排序: 每一轮在当前未排序区间里,同时找出最小值和最大值,把最小值扔到最左边、最大值扔到最右边,然后左右边界各往里缩一位。 ①用 i 和 j 两个指针标记当前未排序区间的左右边界。 ②遍历 i 到 j之间的元素,用 mi 和 mx 记录这轮找到的最小值和最大值的下标。 ③先交换最小值到 i 位置。 ④再交换最大值到 j 位置。 ⑤i 往右移,j 往左移,重复直到 i >= j。 
哎嗨~ 看来这个双向选择排序的过程还是so easy的嘛~ 

接下来,要把最大值换到j的位置,如果直接执行arr[j]和 arr[mx]交换的语句,就会导致错误: 
所以,我们要抓住问题的关键,进行针对性的解决。 
对于最大值正好就在i位置,交换之后被搬到了mi的的情况,需要增加语句“找补”一下: 既然最大值实际在mi那里,那把mx修正为mi位置就行啦~ 

02 解题思路 了解双向选择排序的算法模型后,我们再来看代码要填的空: (1)内层循环的范围 minid和maxid都初始化为i,所以j从i+1开始遍历,要包含排序范围内的所有值,也就是到右边界n-i-1结束。 注意range是左闭右开的,要包含到n-i-1,结束值就得写n-i,填range(i+1, n-i),对应②。 (2)if i == maxid 时的修正 先执行了 a[i], a[minid] = a[minid], a[i],把最小值换到了i位置。 如果最大值原本就在i位置(maxid==i),交换后最大值被移到了minid的位置。 所以,要把maxid修正为minid。填maxid = minid,对应⑤。 (3)把最大值换到右边 最右边的位置是n-i-1(第i轮,从右数第i个位置),把maxid位置的最大值和n-i-1位置交换。 填a[n - i - 1], a[maxid] = a[maxid], a[n - i - 1],对应③。 三个空分别是②⑤③,选A走人~ 篇幅有限,如果同学们想深入学习各种排序算法的变形,滴滴一下,朱老师带你拿下它们~ 后台回复:20261004 即可获得视频讲解 关注公众号 — 推荐阅读 — 
【新高三秋季课程】二轮进阶刷题直播课程目录及上课流程!主讲:朱一帆老师 
【27届新高三】技术首考冲刺一轮复习来了!主讲:朱一帆老师 
【高二重难点】选修技术课程目录及上课流程!主讲:朱一帆老师 
【新高二】必修技术教材课程目录及上课流程!主讲:朱一帆老师 
【慎点】2026年技术选考不是玄学,数万名考生亲测有效! 

【例】某升序排序算法,其Python程序段如下:
# 随机产生n个整数存入列表a,代码略n = len(a)for i in range(n // 2):minid = imaxid = ifor j in range(____(1)____):if a[j] < a[minid]:minid = jif a[j] > a[maxid]:maxid = ja[i], a[minid] = a[minid], a[i]if i == maxid:____(2)________(3)____
代码中(1)~(3)处可选的表达式有:
① i + 1, n - i - 1② i + 1, n - i③ a[n - i - 1], a[maxid] = a[maxid], a[n - i - 1]④ a[n - i], a[maxid] = a[maxid], a[n - i]⑤ maxid = minid⑥ minid = maxid
要使程序实现上述排序算法功能,则(1)~(3)处的表达式序号依次为:
A. ②⑤③
B. ①⑤③
C. ①⑥④
D. ②⑥④
01
代码模型
arr = [6, 8, 5, 3, 9, 7]n = len(arr)i = 0 # i是当前未排序区间的左边界j = n - 1 # j是当前未排序区间的右边界while i < j:mi = i # mi记录本轮最小值的索引,先初始化为左边界mx = i # mx记录本轮最大值的索引,先初始化为左边界# 在i到j之间遍历,找最小值和最大值的位置for k in range(i, j + 1):if arr[k] < arr[mi]:mi = k # 找到更小的,更新最小值索引if arr[k] > arr[mx]:mx = k # 找到更大的,更新最大值索引# 把最小值换到最左边i的位置arr[i], arr[mi] = arr[mi], arr[i]# 关键细节:如果最大值原本就在i位置,# 上面交换后最大值被移到了mi的位置,所以要修正mxif mx == i:mx = mi# 把最大值换到最右边j的位置arr[j], arr[mx] = arr[mx], arr[j]# 左右边界各往里缩一位,继续下一轮i = i + 1j = j - 1print(arr)
02
步骤拆解
03
动画演示


Q
在第二轮的排序当中,最大值正好就在i位置,也就是mx==i,在完成arr[i]的 arr[mi]交换之后,最大值就被搬到了mi的位置:



# 如果最大值原本就在i位置# 上面交换后最大值被移到了mi的位置,所以要修正mxif mx == i:mx = mi# 把最大值换到最右边j的位置arr[j], arr[mx] = arr[mx], arr[j]


# 随机产生n个整数存入列表a,代码略n = len(a)for i in range(n // 2): # 每轮能确定最小值和最大值,外层循环执行n//2趟minid = i # minid记录未排序区间最小值的下标maxid = i # maxid记录未排序区间最大值的下标for j in range(____(1)____): # j遍历未排序区间内剩下所有元素if a[j] < a[minid]: # 如果当前j位置元素,比记录的最小值还要小minid = j # 更新最小值下标minid为jif a[j] > a[maxid]: # 如果当前j位置元素,比记录的最大值还要大maxid = j # 更新最大值下标maxid为ja[i], a[minid] = a[minid], a[i] # 将找到的最小值交换到未排序区间最左边的位置i# 特殊情况:最大值原来就在左边界i,刚刚交换后最大值被移到minid位置if i == maxid:____(2)____ # 需要修正最大值下标,把maxid更新为minid____(3)____ # 将找到的最大值交换到未排序区间最右侧的位置

获取技术试题及优质干货





