数据结构之查找(顺序、折半、分块查找,B树、B+树、散列表)

在这里插入图片描述

一、线性结构查找

1、顺序查找
(1)无序的线性查找
基本思想:从线性表的一端开始,逐个检查关键字是否满足给定的条件。特点:当N比较大时,查找效率低。
在这里插入图片描述
(2)有序的线性查找:查效率比无序查找略高。

2、折半查找
基本思想:折半查找又称二分查找,仅适用于有序的顺序表。将给定的值与表中间位置的元素比较,相等则查找成功;不相等则继续在中间元素以外的前半部分或后半部分继续查找;如此重复,直到找到为止,若没有指定元素,则查找失败。
在这里插入图片描述
案例:
在这里插入图片描述
3、分块查找
基本思想:吸取了顺序查找和折半查找各自的优点,既有动态结构,又适于快速查找。将表分为若干子块,块内元素可以无序,块之间必须是有序的。
案例:88、24、72、61、21、6、32、11、8、31、22、83、78、54
在这里插入图片描述

二、树形结构查找

1、B树
B树:又叫多路平衡查找树,B树种所有结点的孩子个数的最大值称为B树的阶,通常用m表示。B树也是所有结点的平衡因子均等于0的多路平衡查找树。

(1)m叉树的特性:

  • 1)树中每个结点至多有m棵子树,即至多含有m-1个关键字;
  • 2)若根节点不是终端结点,则至少有两棵子树;
  • 3)除根结点外的所有非叶节点至少有m/2棵子树,至少有m/2-1个关键字;
  • 4)所有非叶结点的结构如下:
    在这里插入图片描述
  • 5)所有的叶结点都出现在同一层次上,并且不带信息

案例:
在这里插入图片描述
(2)B树的高度范围:
在这里插入图片描述
(3)B树的用途
使用B-tree结构可以显著减少定位记录时所经历的中间过程,从而加快存取速度。这个数据结构一般用于数据库的索引,综合效率较高。

(4)B树的查找
B树的查找:类似二叉排序树的查找,不同的是B树每个结点上是有多个关键字的有序表,在到达某个结点时,先在有序表中查找,若找到,则查找成功;否则,到按照对应的指针信息指向的子树中去查找,当到达叶子结点时,则说明树中没有对应的关键码。
案例:
在这里插入图片描述

  • 1)首先从根节点a开始,因为 a 节点中只有一个关键字35,且给定值47 > 关键字35,则若存在必在指针A1所指的子树内。
  • 2)顺指针找到 c节点,该节点有两个关键字(43和 78),而43 < 47 < 78,若存在比在指针A1所指的子树中。
  • 3)同样,顺指针找到 g节点,在该节点找到关键字47,查找成功。

(4)B树的插入(可能涉及结点的分裂)
案例:3阶B树,假设需依次插入关键字30,26,85。
在这里插入图片描述

  • 1)首先通过查找确定插入的位置。由根节点a开始查找,确定30应插入的在d 节点中。由于d 中关键字数目不超过2(即m-1),故第一个关键字插入完成:如图(b)
    在这里插入图片描述
  • 2)同样,通过查找确定关键字26亦应插入 d, 由于d节点关键字数目超过2,此时需要将 d分裂成两个节点,关键字26及其前、后两个指针仍保留在 d 节点中。而关键字37 及其前、后两个指针存储到新的产生的节点 d中。同时将关键字30 和指示节点 d的指针插入到其双亲的节点中。由于 b节点中的关键字数目没有超过2,则插入完成.如图(c)(d)
    在这里插入图片描述
    在这里插入图片描述
  • 3) (e) -(g) 为插入85后;
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

(5)B树的删除(可能涉及结点的合并操作)

  • 1)被删关键字K不在终端结点,可以用K的前驱或后继k来替代K,然后在相应的结点中删除k,关键字k必定落在某个终端结点中。
    在这里插入图片描述
  • 2)被删的关键字在终端结点中,有三种情况:
    a、直接删除关键字:若被删关键字所在结点的关键字个数≥m/2,则可直接删除关键字;
    b、兄弟够借:若被删关键字所在结点的关键字个数=m/2-1,且与此节点相邻的兄弟结点的关键字个数≥m/2,则需要调整该结点、兄弟结点及其双亲结点,以达到新的平衡;
    在这里插入图片描述
    c:兄弟不够借:若被删关键字所在结点的关键字个数=m/2-1,且与此节点相邻的兄弟结点的关键字个数均=m/2-1,则将关键字删除后与兄弟节点及其双亲节点中的关键字合并。
    在这里插入图片描述

2、B+树
在这里插入图片描述
(1)B+树的特征以及与B树的差别

在这里插入图片描述
(2)每个叶子节点都有一个指针,指向下一个数据,形成一个有序链表。而只有叶子节点才会有data,其他都是索引。

(3)B+树的插入
案例:阶数为5。

  • a)空树中插入5。
    在这里插入图片描述

  • b)依次插入8,10,15,16。
    在这里插入图片描述
    插入16后产生分裂:
    在这里插入图片描述

  • c)插入17,18
    在这里插入图片描述
    插入18后产生分裂:
    在这里插入图片描述

  • d) 插入几个数据后。
    在这里插入图片描述

  • e)再继续插入7。
    在这里插入图片描述
    在这里插入图片描述
    最终的分裂结果:
    在这里插入图片描述

三、散列表

1、散列函数:一个把查找表中的关键字映射成该关键字对应的地址的函数。散列函数可能会把两个或两个以上的不同关键字映射到同一地址,这种情况称为冲突;冲突是不可避免的额,所以要设计处理冲突的方法。

2、散列表:根据关键字直接进行访问的数据结构。

3、构造散列函数的注意事项:
(1)散列函数的定义必须包含全部需要存储的关键字,而值域的范围则依赖于散列表的大小或地址范围;
(2)散列函数计算处理的地址应该能等概率、均匀地分布在整个地址空间中,从而减少冲突的发生;
(3)散列函数应尽量简单,能够在较短的时间内计算出任一关键字对用的散列地址。

4、常用的散列函数
(1)直接定址法
关键码本身和地址之间存在某个线性函数关系时,散列函数取为关键码的线性函数,即:H(key)=a*key+b,a、b均为常数。这样的散列函数优点就是简单、均匀,也不会产生冲突,但问题是这需要事先知道关键字的分布情况,适合査找表较小且连续的情况。由于这样的限制,在现实应用中,直接定址法虽然简单,但却并不常用。

(2)数字分析法
假设关键码完全已知,且每个关键码都是以某个数r为基数(例以10为基数的十进制数)的值,则关键码中若干位恰能构成分布比较均匀的散列地址空间时,可取关键码的若干位的组合作为散列地址。

(3)除留余数法
通过选择适当的正整数p,按计算公式 H(K)=Key%p 来计算关键码K的散列地址。若关键码个数为n,散列表表长为m(一般m>=n),通常选p为小于或等于表长m的最大素数或不包含小于20的质因子的合数,一般也要求p>=n。这种方法计算最简单,也不需根据全部关键码的分布情况研究如何从中析取数据,最常用。

(4)平方取中法
将关键码K平方,取K^2中间几位作为其散列地址H(K)的值。假如有以下关键字序列{421,423,436},平方之后的结果为{177241,178929,190096},那么可以取{72,89,00}作为Hash地址。

5、处理冲突的方法
(1)开放定址法

  • 1)线性探测法
    从发生冲突位置的下一个位置开始寻找空的散列地址。发生冲突时,线性探测下一个散列地址是:Hi=(H(key)+di)%m,(di=1,2,3…,m-1)。闭散列表长度为m。它实际是按照H(key)+1,H(key)+2,…,m-1,0,1,H(key)-1的顺序探测,一旦探测到空的散列地址,就将关键码记录存入。该方法会产生堆积现象,即使是同义词也可能会争夺同一个地址空间,今后在其上的查找效率会降低。
  • 2)平方探测法
    发生冲突时,下一位置的探测采用公式:Hi=(H(key)+di)%m(di=12,-12,22,-22,…,q2,-q2,q<=根号下m)在一定程度上可解决线性探测中的堆积现象。缺点是不能探测散列表上的所有单元,但至少能探测一半的单元。
  • 3)随机探测法
    di为{1,2,3,…,m-1}中的数构成的一个随机数列中顺序取的一个数。
  • 4)再散列函数法
    除基本散列函数外,事先设计一个散列函数序列,RH1,RH2,…,RHk,k为某个正整数。RHi均为不同的散列函数。对任一关键码,若在某一散列函数上发生冲突,则再用下一个散列函数,直到不发生冲突为止。

(2)拉链法
将所有散列地址相同的记录存储在同一个单链表中,该单链表为同义词单链表,或同义词子表。该单链表头指针存储在散列表中。散列表就是个指针数组,下标就是由关键码用散列函数计算出的散列地址。初始,指针数组每个元素为空指针,相当于所有单链表头指针为空,以后每扫描到一条记录,按其关键码的散列地址,在相应的单链表中加入含该记录的节点。开散列表容量可很大,仅受内存容量的限制。
案例:具体的关键字列表为(19,14,23,01,68,20,84,27,55,11,10,79),则哈希函数为H(key)=key MOD 13。则采用除留余数法和链地址法后得到的预想结果应该为:
在这里插入图片描述
6、散列表的性能分析

案例性能分析:

(1)开放定址法的平均查找长度
在这里插入图片描述
ASL成功=(1+1+1+3+4+1+2+8)/8=21/8
ASL失败=(9+8+7+6+5+4+3+2+1+1+1)/11=47/11

(2)拉链法的平均查找长度
在这里插入图片描述
ASL成功=(1x6+2x4+3x1+4x1)/12=21/12=1.75
ASL失败=(1+5+1+3+1+1+3+2+1+1+3+2+1)/13=25/13

(3)装填因子
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值