计算机中级-数据库系统工程师-数据结构-查找算法

一、查找算法
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次),但适应面广 | ⭐ |
| 折半查找(二分) | 要求有序表,每次比较中间元素,缩小一半范围 | 必须有序,判定树层数决定最大比较次数 | ⭐⭐⭐ |
| 索引顺序查找(分块) | 块内无序、块间有序,额外维护索引表(最大关键字+起始地址) | 先查索引定位块,再块内顺序查找 | ⭐⭐ |
| 哈希查找 | 关键字通过哈希函数直接映射地址,需处理冲突(开放定址/链地址) | 哈希函数设计与冲突解决策略 | ⭐⭐⭐⭐ |
| 二叉查找树 | 动态查找表,左子树<根<右子树,查找过程可能动态建树 | 插入顺序影响树结构,退化为链表的极端情况 | ⭐⭐⭐ |
| 开放定址法 | 冲突时按增量序列(线性/二次/随机)探测空位 | 聚集现象导致效率下降 | ⭐⭐⭐ |
| 链地址法 | 冲突元素组织成链表,哈希地址存指针 | 指针空间开销,但避免聚集 | ⭐⭐⭐ |

相关推荐
所以遗憾是什么呢?2 小时前
【题解】Codeforces Round 1081 (Div. 2)
数据结构·c++·算法·acm·icpc·ccpc·xcpc
xiaoye-duck3 小时前
《算法题讲解指南:递归,搜索与回溯算法--综合练习》--14.找出所有子集的异或总和再求和,15.全排列Ⅱ,16.电话号码的字母组合,17.括号生成
c++·算法·深度优先·回溯
OOJO3 小时前
c++---vector介绍
c语言·开发语言·数据结构·c++·算法·vim·visual studio
茉莉玫瑰花茶3 小时前
数据结构 - 并查集
数据结构
汀、人工智能3 小时前
05 - 函数基础
数据结构·算法·数据库架构·05 - 函数基础
HAPPY酷3 小时前
Python高级架构师之路——从原理到实战
java·python·算法
枫叶林FYL3 小时前
第9章 因果推理与物理理解
人工智能·算法·机器学习
小白zlm4 小时前
预畸变双线性变换
单片机·嵌入式硬件·算法·电机控制
wuweijianlove4 小时前
算法复杂度估算的实验建模与可视化表达的技术6
算法