Appearance
题目
使用直接插入排序对序列进行升序排序,以下比较次数最少的是()。
错因
A
只看了 A 序列前两项 (30, 27) 是逆序,没逐个数比较次数。逐个数下来 A 总共 9 次,确实比 B 多 1 次。直觉判断"反转少 = 比较少"在 A 与 B 之间已经分不出来,必须实际数。
C
C 含多次大幅反转(51 < 84,23 是当前最小要插到最前,最后 40 又要往前插 5 次),逐位算下来高达 16 次,是四个里最多之一。选 C 的人估计盯着前两项 (61, 84) 是顺序就放心了,没意识到中段 23 是局部最小、尾部 40 也偏小。
D
D 同样是 16 次。开头 93 是大数,紧接着 32 又比所有前面的小,21 又是全局最小要插到最前——一连串"小数往前插"的代价非常重。选 D 的人可能误以为开头大数会让后面比较变少,但实际"前面已排序部分越长、后面要插的小数越深",比较次数反而越大。
总解析
核心规律:直接插入排序对第 i 个元素 (i ≥ 2),从已排序部分末尾向前比较,直到找到合适位置或越界。最好情况(已升序)每个新元素只比 1 次,总比较 n−1;最坏情况(已降序)第 i 个元素比 i 次,总比较 。
逐项数比较次数(n=7,对 a[2..7] 共 6 个元素插入):
A. 30, 27, 56, 41, 80, 95, 69
| 插入 | 已排序前缀 | 比较过程 | 次数 |
|---|---|---|---|
| 27 | [30] | 27<30 → 越界 | 1 |
| 56 | [27,30] | 56>30 | 1 |
| 41 | [27,30,56] | 41<56, 41>30 | 2 |
| 80 | [27,30,41,56] | 80>56 | 1 |
| 95 | [27,30,41,56,80] | 95>80 | 1 |
| 69 | [27,30,41,56,80,95] | 69<95, 69<80, 69>56 | 3 |
合计 9 次。
B. 31, 43, 26, 55, 63, 99, 77
| 插入 | 比较过程 | 次数 |
|---|---|---|
| 43 | 43>31 | 1 |
| 26 | 26<43, 26<31 → 越界 | 2 |
| 55 | 55>43 | 1 |
| 63 | 63>55 | 1 |
| 99 | 99>63 | 1 |
| 77 | 77<99, 77>63 | 2 |
合计 8 次。✓ 最少。
C. 61, 84, 51, 23, 34, 91, 40
逐项算:1 + 2 + 3 + 4 + 1 + 5 = 16 次。
D. 93, 32, 48, 81, 50, 21, 72
逐项算:1 + 2 + 2 + 3 + 5 + 3 = 16 次。
汇总:A=9,B=8,C=16,D=16。
观察 B 序列的结构:除了 26 要插到最前(贡献 2 次比较)和 77 略往前插(2 次),其余都是后一个数大于已排序末尾,每次只 1 次比较——B 序列"基本升序"的程度最高。
最终答案是 B。