一、查找算法
1. 查找表与查找效率
1)查找表的定义
- 集合特性: 由同一类型的数据元素(或记录)构成的集合,用于存储和查找特定数值。例如存储整数序列{1,3,5,7}的集合。
- 操作对象: 在查找表中进行查找操作时,需要明确查找目标的数据类型必须与表中元素类型一致。
2)静态查找表与动态查找表
- 静态操作: 仅支持查询(如判断元素是否存在)和检索(获取元素信息)两种操作。例如查询数字8是否在表{1,3,5,7}中。
- 动态操作: 除查询检索外,还支持插入和删除操作。例如查找数字8不存在时将其插入表尾,或查找数字7存在时将其删除。
- 典型区别: 静态表结构固定,动态表结构可变。教材案例中演示了动态表插入8和删除6的操作过程。
3)关键字与查找的定义
- 标识作用: 关键字是数据元素中用于唯一标识该元素的特定数据项值。如记录中的学号字段。
- 查找过程: 给定目标值后,在表中逐个比较记录关键字,直到找到匹配项或遍历完整个表。例如用值7在表{1,3,5,7}中查找需要比较4次。
4)平均查找长度(ASL)的概念
- 效率指标: 通过统计关键字比较次数的平均值来衡量算法优劣。例如顺序查找7需要比较4次,若优化算法只需1次则效率显著提升。
- 计算原理: ASL=(∑i=1n比较次数i)/n,其中n为查找操作总次数。比较次数越少,算法效率越高。
2. 顺序查找
- 基本流程: 从表的一端(左/右)开始逐个比较,直到找到匹配项或遍历完整个表。例如查找13需要比较7次(按序列7,14,3,10,6,12,11,13)。
- 失败情况: 查找20时需要比较完所有15个元素才能确认不存在。
- 算法特点:
- 优点:实现简单,适用于任何存储结构(顺序/链式)
- 缺点:时间复杂度O(n),表长较大时效率显著下降。例如1万条记录最多需比较1万次。
3. 折半查找
1)核心算法
- 前提条件:
- 必须采用顺序存储结构
- 关键字有序排列(升序/降序)
- 查找步骤:
- 取中间记录与目标值比较
- 相等则成功;不等则根据大小关系缩小至左/右半区
- 重复直至找到或区间为空
- 实例演示: 在有序表1-15中查找13的过程:
- 第1次比较8→右半区
- 第2次比较12→右半区
- 第3次比较14→左半区
- 第4次找到13
- 效率对比: 比顺序查找的13次比较减少到4次,提升显著
2)折半查找判定树
- 树形表示: 将查找过程抽象为二叉树,根节点为中间记录,左右子树对应左右半区
- 构造规则:
- 结点:查找过程中的中间记录(如8,4,12等)
- 左子树:小于当前记录的所有元素
- 右子树:大于当前记录的所有元素
- 性能特征:
- 树高决定最大比较次数(示例中4层对应最多4次比较)
- 平衡性保证每次查找都能有效缩小范围
4. 树表查找
1)二叉查找树的概念
- 动态查找表特性: 二叉查找树是一种动态查找表,表结构本身在查找过程中动态生成,支持查询、插入和删除操作。
- 别名与性质: 又称二叉排序树,满足左子树所有结点值小于根结点值,右子树所有结点值大于根结点值的特性。
2)动态查找表与静态查找表的区别
- 静态查找表: 仅支持查询和检索操作,表结构固定不变。
- 动态查找表: 除查询外还支持插入和删除操作,表结构可动态变化,二叉查找树是典型代表。
3)二叉查找树的创建过程
- 示例序列: 以{46,25,54,13,29,91}为例演示创建过程:
- 空树时,46作为根结点
- 25<46,成为46的左孩子
- 54>46,成为46的右孩子
- 13<46且<25,成为25的左孩子
- 29<46但>25,成为25的右孩子
- 91>46且>54,成为54的右孩子
- 动态性体现: 查找过程中若树不存在,则按关键字顺序动态创建。
4)二叉查找树的查找过程
- 查找原理: 从根结点开始比较:
- 目标值<当前结点:进入左子树
- 目标值>当前结点:进入右子树
- 示例查找29:
- 46>29→左子树
- 25<29→右子树
- 找到29
5. 索引顺序查找
1)索引顺序查找的概念与改进点
- 别称: 又称分块查找
- 改进本质: 对顺序查找的优化,通过建立索引提高效率
2)索引顺序查找的原理
- 分块规则:
- 将表分成若干块
- 块内元素无序
- 块间有序(后一块所有关键字大于前一块)
- 示例分块:
- 块1(1-6地址): 最大关键字23
- 块2(7-12地址): 最大关键字49
- 块3(13-18地址): 最大关键字87
3)索引表的创建与作用
- 索引表内容:
- 最大关键字:记录每块的最大值
- 起始地址:记录每块的起始存储位置
- 示例索引表:
4)索引顺序查找的步骤
- 查找50的流程:
- 查索引表:50>49且50<87→定位到第三块
- 根据起始地址13定位到存储区域
- 在块内进行顺序查找(比较61,59,75,50)
5)索引顺序查找的效率分析
- 优势: 相比纯顺序查找,通过索引快速定位块,减少比较次数
- 代价: 需要额外存储空间存放索引表
6. 哈希查找
1)传统查找方法的局限性
- 关键问题: 关键字与存储地址无直接关联,必须通过比较查找
2)哈希函数原理
- 函数定义:H_i=Hash(Key),关键字作为自变量,存储地址作为因变量
- 示例函数:H=Key mod 3
- 关键字3→地址0
- 关键字4→地址1
- 关键字5→地址2
3)冲突问题
- 冲突定义: 当K1≠K2但Hash(K1)=Hash(K2)时发生冲突
- 示例冲突: 关键字3和6对3取模结果均为0
- 核心问题:
- 哈希函数构造
- 冲突解决方法
- 函数优化示例: 对6取模可避免1-6关键字的冲突
7. 哈希查找
1)冲突的处理
- 开放定址法
- 基本公式:Hi=(Hash(key)+di)%m,其中i=1,2,...,k(k≤m−1),Hash(key)为哈希函数,m为哈希表表长,di为增量序列
- 增量序列类型:
- 线性探测:di=1,2,3,...,m−1,依次向后移动寻找空位
- 二次探测:d_i=1^2,-1^2,2^2,-2^2,...,±k^2(k≤m/2),交替向左右探测
- 随机探测:di为伪随机序列,随机移动位置
- 工作原理:当发生冲突时,按照增量序列寻找下一个空位存储
- 特点:可能导致元素聚集现象(二次聚集),影响查找效率
- 例题:开放定址法哈希表构造
- 题目解析:
- 关键码序列:47,34,19,12,52,38,33,57,63,21
- 哈希函数:Hash(key)=key mod 11
- 表长:13
- 冲突处理:线性探测法
- 构造过程:
- 47 mod 11=3 → 存入地址3
- 34 mod 11=1 → 存入地址1
- 12 mod 11=1(冲突)→ 向后移动1位存入地址2
- 52 mod 11=8(冲突)→ 向后移动1位存入地址9
- 57 mod 11=2(冲突)→ 向后移动2位存入地址4
- 63 mod 11=8(冲突)→ 向后移动2位存入地址10
- 21 mod 11=10(冲突)→ 向后移动1位存入地址11
- 最终结果:
- 哈希地址:0 1 2 3 4 5 6 7 8 9 10 11 12
- 关键码:- 34 12 47 57 38 - - 19 52 63 21 -
- 题目解析:
- 链地址法
- 基本原理:将具有相同哈希值的记录组织成链表,哈希表中存储指针而非关键字
- 存储结构:
- 每个哈希地址对应一个链表头指针
- 冲突元素以节点形式链接在对应链表后
- 特点:
- 不会产生聚集现象
- 空间利用率高(动态分配节点)
- 查找时需要遍历链表
- 例题:链地址法哈希表构造
- 题目解析:
- 关键码序列:47,34,12,52,38,33,27,3
- 哈希函数:Hash(key)=key mod 11
- 表长:11
- 构造过程:
- 47 mod 11=3 → 创建节点存入47,地址3指向该节点
- 34 mod 11=1 → 创建节点存入34,地址1指向该节点
- 12 mod 11=1(冲突)→ 创建新节点存入12,链接在34节点后
- 3 mod 11=3(冲突)→ 创建新节点存入3,链接在47节点后
- 查找过程:
- 查找52:计算哈希值8,直接访问地址8指向的节点
- 查找21:计算哈希值10,发现地址10指针为空,查找失败
- 查找63:计算哈希值8,依次比较链表节点(52≠63),直到指针为空
- 题目解析:
二、知识小结
|------------|-----------------------------------|----------------------|------|
| 知识点 | 核心内容 | 考试重点/易混淆点 | 难度系数 |
| 查找表定义 | 同一类型数据元素构成的集合,分静态(仅查询)和动态(含插入/删除) | 静态与动态查找表的区别 | ⭐⭐ |
| 顺序查找 | 从一端逐个比较,成功即返回,全表未找到则失败 | 效率低(最坏比较n次),但适应面广 | ⭐ |
| 折半查找(二分) | 要求有序表,每次比较中间元素,缩小一半范围 | 必须有序,判定树层数决定最大比较次数 | ⭐⭐⭐ |
| 索引顺序查找(分块) | 块内无序、块间有序,额外维护索引表(最大关键字+起始地址) | 先查索引定位块,再块内顺序查找 | ⭐⭐ |
| 哈希查找 | 关键字通过哈希函数直接映射地址,需处理冲突(开放定址/链地址) | 哈希函数设计与冲突解决策略 | ⭐⭐⭐⭐ |
| 二叉查找树 | 动态查找表,左子树<根<右子树,查找过程可能动态建树 | 插入顺序影响树结构,退化为链表的极端情况 | ⭐⭐⭐ |
| 开放定址法 | 冲突时按增量序列(线性/二次/随机)探测空位 | 聚集现象导致效率下降 | ⭐⭐⭐ |
| 链地址法 | 冲突元素组织成链表,哈希地址存指针 | 指针空间开销,但避免聚集 | ⭐⭐⭐ |