| 项目 | 值 |
|---|---|
| 主题 | 查找算法对比 |
| 核心概念 | 查找(Searching)是从数据集合中找出满足条件元素的过程 |
| 时间复杂度 | $O(1)$、$O(\log n)$、$O(\log_m n)$、$O(\sqrt n)$、$O(n)$ |
| 难度 | ⭐⭐⭐ |
| 重要性 | ⭐⭐ |
查找(Searching)是从数据集合中找出满足条件的元素的过程。主要查找算法包括:
| 算法 | 数据结构 | ASL(成功) | ASL(失败) | 适用条件 |
|---|---|---|---|---|
| 顺序查找 | 顺序表/链表 | (n+1)/2 | n | 无要求 |
| 折半查找 | 有序顺序表 | $\approx\log_2(n+1)-1$ | $\approx\log_2(n+1)$ | 有序 + 顺序存储 |
| 分块查找 | 索引表+主表 | $\sqrt n+1$ | - | 块间有序 |
| BST 查找 | 二叉搜索树 | (n+1)/3 ~ n | n+1 | 无 |
| AVL 查找 | 平衡二叉树 | $\approx1.44\log_2n$ | - | 平衡 |
| B 树查找 | m 阶 B 树 | $O(\log_m n)$ | - | 多路平衡 |
| 散列查找 | 散列表 | $O(1)$ | - | 散列函数 |
int SeqSearch(ElemType A[], int n, KeyType key) {
for (int i = 0; i < n; i++)
if (A[i] == key) return i;
return -1;
}
带哨兵的顺序查找:
int SeqSearch2(ElemType A[], int n, KeyType key) {
A[0] = key; // 哨兵
int i = n;
while (A[i] != key) i--;
return i; // 返回 0 表示失败
}
ASL成功:(n+1)/2(不变),但减少了一次比较判断。
int BinarySearch(ElemType A[], int n, KeyType key) {
int low = 0, high = n - 1;
while (low <= high) {
int mid = (low + high) / 2;
if (A[mid] == key) return mid;
else if (A[mid] < key) low = mid + 1;
else high = mid - 1;
}
return -1;
}
详见 分块查找。
题目:1000 个元素,求各算法的成功 ASL。
| 算法 | ASL 计算 | 结果 |
|---|---|---|
| 顺序查找 | (1000+1)/2 | 500.5 |
| 折半查找 | $\log_2(1001)-1$ | $\approx9$ |
| 分块查找 | $\sqrt{1000}+1$ | $\approx32.6$ |
| AVL 树 | $1.44\times\log_21000$ | $\approx14.4$ |
| 散列表 | 取决于 $\alpha$ | $\approx O(1)$ |
题目:对有序表 (1,3,5,7,9,11,13,15) 构造折半查找判定树。
第一次:$mid=(0+7)/2=3$,$A[3]=7$;左半:(0,2),右半:(4,7)。
左半:$mid=(0+2)/2=1$,$A[1]=3$;左左:(0,0),左右:(2,2)。
右半:$mid=(4+7)/2=5$,$A[5]=11$;右左:(4,4),右右:(6,7)。
右右:$mid=(6+7)/2=6$,$A[6]=13$;右右左:无,右右右:(7,7)。
7
/ \
3 11
/ \ / \
1 5 9 13
\
15
查找成功 ASL = $(1\times1 + 2\times2 + 3\times4 + 4\times1) / 8 = (1+4+12+4)/8 = \frac{21}{8} = 2.625$
查找失败 ASL = 考虑外部节点(空指针)。
题目:有 10 个元素,散列表大小 13,用链地址法,装填因子 $\alpha=10/13$。
ASL成功 $\approx 1 + \alpha/2 = 1 + \frac{10}{26} \approx 1.38$
ASL失败 $\approx 1 + \alpha = 1 + \frac{10}{13} \approx 1.77$
| 场景 | 推荐算法 | 原因 |
|---|---|---|
| 数据量小 | 顺序查找 | 实现简单 |
| 有序数组 | 折半查找 | $O(\log n)$ |
| 频繁插入删除 | BST / AVL / 散列表 | 动态结构 |
| 外部存储 | B 树 / B+ 树 | 减少磁盘 I/O |
| 追求 $O(1)$ | 散列表 | 最快 |
(暂无关联知识点)—— 本卡片为 06-search 章节的总结对比,未设置关联链接。