Appearance
题目
下列数据结构中,不适合直接使用折半查找的是( )
I. 有序链表 II. 无序数组 III. 有序静态链表 IV. 无序静态链表
错因
A
只承认 I 和 II 不适合,把 III、IV(静态链表)当成普通数组对待。静态链表虽然底层是数组,但元素之间的"逻辑顺序"由结点里的 next 字段(数组下标)维护,物理下标和逻辑次序对不上——折半查找需要的是"按逻辑序号 O(1) 找到中点",静态链表做不到,必须沿 next 链一步步走。所以 III、IV 同样不适合。
B
抓住了"无序就不能折半"这一条,但漏掉了"必须随机存取"这一条。I(有序链表)虽然有序,可链表无法 O(1) 定位中点,每次"取中点"都要从头走过半个链表,整体复杂度退化到 比直接顺序查找还差。III(有序静态链表)同理。
C
承认 I、II、IV 不适合,却把 III(有序静态链表)当成"既然有序,也可以折半"。错在没有意识到静态链表里的"有序"指的是 next 链顺序的有序,而不是数组下标顺序的有序——访问"逻辑中点"仍需沿 next 走 步,达不到 O(1) 的随机存取要求。
总解析
折半查找的两个必要前提:
- 数据有序——才能根据"中点元素 vs 待查关键字"的比较结果决定下一步去左半区还是右半区。
- 支持随机存取(O(1) 定位任意位置元素)——才能用
mid = (low+high)/2直接拿到中点;如果取一次中点要 O(n),折半就失去了 的复杂度优势。
逐项判断:
| 选项 | 有序? | 随机存取? | 适合折半查找? |
|---|---|---|---|
| I 有序链表 | ✓ | ✗(链表只能顺序遍历) | ✗ |
| II 无序数组 | ✗ | ✓ | ✗ |
| III 有序静态链表 | ✓(按 next 链有序) | ✗(逻辑序 ≠ 数组下标,取中点要走链) | ✗ |
| IV 无序静态链表 | ✗ | ✗ | ✗ |
关于静态链表的关键认知:静态链表 = 用数组模拟的链表,结点用数组实现但邻接关系靠 next 字段(存的是数组下标)维护。物理下标连续 ≠ 逻辑顺序连续——例如有序静态链表里逻辑上的第 1 个元素可能在数组下标 7,第 2 个在下标 2,第 3 个在下标 5……要找逻辑上的中间元素必须从首结点出发沿 next 走 步,不能直接 arr[mid] 取。这就是它不能折半查找的根本原因。
四种结构全部不满足两个前提的并集,所以全部都不适合直接使用折半查找。
最终答案是 D(I、II、III、IV)。