《考研408数据结构》第七章(7.1 查找:顺序查找、折半查找、分块查找)复习笔记

一、概念

1、基本术语概念

  • 【三个术语】
    • 【查找】、【查找表】、【关键字】
  • 【两种基本操作】
    • 【只查不改】or【又查又改】

2、【查找算法】的【评估指标】

1)【ASL(平均查找次数)】

  • 由于我之前在【操作系统:文件系统(文件逻辑结构)】部分研究【顺序文件的平均查找次数】时写过笔记,因此不再过多描述,我个人的笔记如下图所示:

2)【查找成功】和【查找失败】两种情况下的ASL

  • 【查找成功】的【平均查找次数ASL】
  • 【查找失败】的【平均查找次数ASL】

二、顺序查找

1、简单解释算法

2、代码理解

  • 代码非常简单啊,写过代码的都会写
  • ★【哨兵模式】对比:注意还有一种算法是【哨兵模式】,就是把关键字放在【数组第0位】,从后往前对比,每个元素都和哨兵对比,直到找到、或者i到哨兵的位置

3、【算法评估指标:ASL】

  • 成功的ASL :因为查每个元素概率都一样是1/n,所以就是【(1+2+3+...+n/n)】=【n+1/2】
  • 失败的ASL :不用算了,因为只要关键字查找失败,那必然是要遍历整个数组【n】

哨兵模式下】

  • 成功的ASL :一样
  • 失败的ASL :n+1(因为数组多了哨兵这1位元素要遍历)

4、【优缺点】

5、【有序】的【顺序查找】

记住:【有序顺序查找】比【乱序的顺序查找】唯一牛逼的地方只体现在【查找失败】

【例题】

三、折半查找

1、解释算法逻辑

首先只能适用于【有序 的 顺序表】

  • 就是二分查找,设置【左区间下限low】、【中间值mid】、【右区间上限high】
  • 每次对比查找时,【关键字】和【mid】去对比
    • 【小于mid】就说明在【左区间】
      • 那么就只用去左边找,把【右边上限high】缩小到【mid的左边区间】
    • 【大于mid】就说明在【右区间】
      • 那么就只用去右边找,把【左边上限low】放大到【mid的右边区间】
    • 【等于mid】就说明刚好【找到了!!!】
      • mid每次区间变化后,【mid】都更新为【low+high / 2 (注意:向下取整)】
    • 记住:【查找成功是:关键字 = mid】、【查找失败是:low > high(倒反天罡)】

2、代码理解

3、【算法评估ASL】和【折半查找判定树】

  • 【折半查找判定树】
    • 每个左、右区间都可以进一步把【mid】作为【子树的根节点】
      • 又分出一棵子树,逐渐构成一整个完整树
  • 【折半查找判定树】性质分析
    • 1)首先直到因为【mid的向下取整的性质】
      • 所以【偶数时:左区间少于右区间1个】、【奇数时:左右区间一样】
      • 而且说明【右子树节点数 和 左子树节点数 之差是:0或1】
        • 【重视这个知识点】:可以快速判断一棵树是否符合【折半查找树】
      • 那么【左子树和右子树深度只差不超过1】
        • 所以**【折半查找树】必然是【平衡二叉树】** (而【平衡二叉树】又类似于【完全二叉树】)
    • 2)【查找成功的情况】
      • 该折半查找树的必然是一个平衡二叉树,可以发现:查【第i层某个数】刚好就是【查i次】(比如查到13,先查第一次29、再到第二层13,共两次)
      • 所以,假设该折半查找树有m层、n个节点
        • 【平均查找次数ASL】=【1*1+2*2+...+m*m】/【n】
    • 3)【查找失败的情况】
      • 可以发现:查失败必然是【每条路径左 / 右走到头】,也就是【该折半查找树的空指针域】
      • 所以,假设该折半查找树有n个节点
        • 则会有**【n+1】个【空链域】** ,也就是**【n+1】个【失败节点】**
        • 所以: 【平均查找失败次数ASL】=【最少查找失败次数*n-1层失败节点数 + 最多查找失败次数*n层失败节点数】/【n+1(失败节点数)】
        • 例子:
  • 4)折半查找树的【树高】
    • 【n个节点的平衡二叉树】的最大高度是:【log2(n+1)】
      • 【回顾完全二叉树高度h】
  • 5)时间复杂度
    • 已知树高是【log2(n+1)】
    • 而无论【查找成功次数】、还是【查找失败次数】最多都【不会超过树高】
    • 所以按时间复杂度计量:【log2(n+1)】的数量级是【O(log2(n+1))】
    • 【但是注意】:
      • 并非任何情况下【折半查找】永远比【顺序查找】更快
      • 在【关键字就在数组首位】的情况,明显【顺序查找】更快
  • 【还有一个重点】!!!!
    • 【折半查找树】的【中序遍历】一定是【升序】
      • 【例题】

【例题】

  • 注意:老是忘记的话就这么记忆

四、分块查找

1、基本概念理解

  • 用【索引表】记录数组里的【大小不等的、连续的块】
    • 而这些【大小不等的、连续的块】里才是【关键字要对比的元素】
    • 【块之间:有序】、【块内:无序】(联想到计组、操作系统里的内存、磁盘分块,那些是反过来:块之间无序,块内必须连续)

2、解释算法逻辑

1)顺序分块查找

  • 【索引表关键字】 记录的元素是数组【每个块里的 "最大元素"】
  • (注意:而且索引表的关键字数组的元素 都必须是 升序排列
    • 那么关键字顺序遍历索引表,只用比较自己是否大于这个【索引表元素】
      • 如果【大于索引表元素】,说明【不在这个块】;
      • 如果【小于等于这个索引表元素】,说明【在这个块】
        • 那么找到【这个块内】的【第1位元素位置】
          • 接着顺序遍历块内,直到找到元素,查找成功;
          • 如果【在这个块内找不到,从而超出该分块范围去查找】就说明该数组查找失败!

2)折半分块查找

  • 因为分块查找是【按顺序排列】的,那自然也可以利用【折半查找】对其升级!
    • 【查找成功】
      • 在【索引表关键字对比】时就【查找成功】
      • 在【索引表关键字对比】时【查找失败】,但在【数组块内查找成功】
        • 分析:【为什么要在low所指的块内查找】
          • 如果此时一直在索引表查找,索引表查找失败的标志是【low>high】
          • 然而在快失败之前一步,必然是【mid=low=high】,三指针并在一起
          • 如果【关键字 > mid】,说明应该在【mid右边查】,low会左移1位,此时【low > high】
          • 而【mid = (low + high) / 2】必然是偏向左边,也就是原本【mid=low=high】位置,可是刚刚已经对比过了【关键字大于那】
          • 所以只可能是在【右移后的low】所在的块,如果还找不到,那就是真实查找失败了
    • 【查找失败】
      • 而如果**【low】直接跑出索引表外了,那100%查找失败了**

3、【算法评估指标:ASL】

我用最直白、最不绕弯子的方式告诉你:

  • 就是【2个数组的顺序查找ASL相加】:
    • 【索引表的顺序查找ASL】+【该数组块内顺序查找ASL】
    • 【ASL最小情况】
      • 【S】=【数组分成几块】=【块内数组长度】
      • 【S】=【根号n(n是整个数组长度)】时,ASL最小
        • 【导数证明】
        • 【基本不等式证明】
      • 字面理解:
        • 就是把【长度n的数组】平均分成【n个数组分块】
        • 这n个【数组分块】里面,每块又分成【n个元素】
        • 联想:《操作系统------文件系统之逻辑结构》里的索引表分组!!!

【例题】

【小难】

相关推荐
金伟API10247 小时前
常见的SQL面试题:经典50例
数据库·人工智能·笔记·sql·学习
壹号用户8 小时前
c++入门之list了解及使用
数据结构·list
来一碗刘肉面8 小时前
什么是双端队列
数据结构·链表
逸模9 小时前
多业态连锁,如何同步铺开各类门店
大数据·人工智能·笔记·工程·公装·连锁店
流浪0019 小时前
数据结构篇(五):线性表——栈
数据结构·c++·算法
拂拉氏10 小时前
【知识讲解】 链式哈希表的实现与unordered_map和unordered_set的封装
数据结构·哈希算法·散列表
乐橙开放平台10 小时前
明厨亮灶笔记:乐橙轻应用 H5 + 小程序插件,一套 BFF 出两张播放凭证
人工智能·笔记·物联网·小程序·音视频·notepad++
haolin123.10 小时前
数据结构--二叉树
数据结构
不如语冰10 小时前
AI大模型入门-参数的传递
数据结构·人工智能·pytorch·python