数据结构 — 查找II

4分块查找(索引顺序查找

                  

                   【基本思想】将查找表分成若干子块。块内元素可以无序(有序的话,折半查找更                  ),但块之间是有序的(即第一个块的最大关键字小于第二个块中所有记录关键              ),依次类推第二块,第三块。  再建立一个索引表,索引表中的每个元素含有                   各块的最大关键字和各块中第一个元素的地址,索引表按关键字有序排列。

                  

                   【查找步骤】:第一步在索引表中确定带查记录所在的块(顺序查找或者折半查找);              第二步在块内顺序查找。

 

                   【效率分析】

                   假设索引查找和块内查找的平均查找长度为Li,Ls,则

                                     ASL= Li + Ls

                   设将长度为n的查找表均匀分成b块,每块s条记录,在等概率情况下,若在块内           和索引表都采用顺序查找,则

   

 

树形结构

 

       B树

       【定义】又称多路平衡查找树,B树中所有结点的 称为B树的阶,通常用m表示。

       【性质】

1.       树中每个结点至多有m棵子树(即至多有m-1个关键字)

 

2.       若根结点不是终端结点,则至少有两棵子树(也可能只有一个根结点

 

3.       除根结点外,所有非叶结点(包括终端顶点)至少有 棵子树(即至少含有  -1个关键字) 【原因:粗略的理解是为了保证B树平衡,因为B树是所有结点平衡因子均等于0。如果某一结点子树太少,必然导致失衡。】


4.       所有非叶结点结构如下




5 所有叶结点都出现在同一层次上,并且不带信息(类似于折半查找判定树的失败结点)





【应用】

                           

 

1.        B树的高度(磁盘存取次数)[h1] 

 

为毛和磁盘存取次数有关,咋不是在内存总进行的呢?

答:B 树是为了磁盘或其它存储设备而设计的一种多叉平衡查找树,是一种外存数据结构

 

【注】

B-树上操作的时间通常由存取磁盘的时间和CPU计算时间这两部分构成

与高速的CPU计算相比,磁盘I/O要慢得多,所以有时忽略CPU的计算时间,只分析算法所需的磁盘访问次数(磁盘访问次数乘以一次读写盘的平均时间(每次读写的时间略                    有差别)就是磁盘I/O的总时间)。 

B-树上大部分基本操作所需访问盘的次数均取决于树高h。关键字总数相同的情况下B-树的高度越小,磁盘I/O所花的时间越少。

 

 首先明确:B树的高度不包括最后的不带任何信息的叶结点所在那  一层。

                    

如果n1,则对任意一棵包含n个关键字,高度为h,阶数为m的B树:

1)       因为B树中每个结点最多有m个子树,m-1个关键字,所以在一棵高度为h的m阶B树中关键字个数应满足  



         2)     若让每个结点的关键字个数达到最少,则容纳同样多关键字的B 树高度可达最大

 

                 


1.        B树的查找

 

特点】:多路分支决定(二叉查找树是二路分支)

 

【操作】:1)在B树中查找结点 2)在结点内查找关键字。

                 由于B树常存储在磁盘上,则前一个查找操作是在磁盘上进行的[h1] ,而后一个操作是在内存中进行的,即在查找到目标结点后,先将结点中的信息读入内 存,然后采用顺序查找法或折半查找法查找等于k的关键字

                                    

【查找过程】

                  在B树中查找到某个结点后,先在有序表中进行查找(每个节点的关键字都是有序排列的,B树的定义),若找到,则查找成功,否则按照对应的的指针信息所指的子树中去查找。当查找到叶结点(对应指针为空),则说明树中没有对应的关键字。 【可见查找时间复杂度与树高h成正比,不管是查找成 功还是查找失败

 

2.        B树的插入

 

【特点】 在B树中找到插入位置后,插入可能导致整棵树不满足B树定义中的要求,即结点内关键字个数小于m-1。同比二叉查找树,只需找到插入位置直接插入即可即可

 

【插入过程】——>要解决可能存在不满足定义的矛盾

1)  定位:利用B树查找算法,找出插入该关键字的最底层中某个非叶结点(即终端结点,注意B树的插入关键字一定是插在最底层某个非叶子节点内,和二叉平衡树(二叉查找树也是,不过不需要调整平衡)一样插在终端结点后,其代价要小,要是插在中间,调整平衡的代价太大

2)  在B树中,每个非失败节点的关键字个数都在之间。插入后检查被插入结点内关键字的个数。当插入后结点的关键字个数小于m可以直接插入;否则,必须对结点进行分裂。

 

【分裂方法】

取一个新结点,将插入key后的原结点从中间位置⌈m/2⌉)将其中关键字分为两部分,左部分包含的关键字放在原结点中,右部分包含的关键字放在新的结点中,中间位置(⌈m/2⌉)的结点插入到原结点的父结点中,若此时导致其父结点的关键字个数也超过了上限,则继续分裂操作,直至  这个过程传到根结点,导致树高加1.

 












### B+与分块查找的区别对比 B+与分块查找虽然都涉及将数据划分为多个“块”或“节点”来提升查找效率,但它们在数据结构查找机制以及应用场景上存在显著差异。 #### 数据结构差异 B+是一种自平衡的多叉结构,其所有数据都存储在叶子节点中,而非叶子节点仅包含用于索引的关键字。这种设计使得每个节点可以容纳更多的关键字,从而减少的高度,提升查找效率。此外,B+的叶子节点之间通过指针相连,形成一个链表结构,便于进行范围查询和顺序访问[^3]。 分块查找则是将数据分成若干块,每一块内部的数据可以是无序的,但块与块之间的关键字是有序的。查找时,首先在索引表中查找目标关键字所属的块,然后在该块内部进行顺序查找。这种结构在实现上较为简单,但缺乏B+那样的自动平衡能力[^2]。 #### 查找机制差异 在B+中,查找操作总是从根节点开始,沿着的层级逐级向下,直到到达叶子节点。由于所有数据都在叶子节点中,因此无论查找成功与否,最终都会到达叶子节点层。这种设计确保了查找操作的稳定性[^5]。 分块查找则涉及两个阶段:首先在索引表中查找目标关键字所在的块,然后在该块内部进行顺序查找。索引表可以使用顺序查找或二分查找,而块内部的查找则只能是顺序查找。由于索引表的存在,分块查找在某些情况下可能比B+更快,尤其是在数据分布较为均匀的情况下[^2]。 #### 插入与删除操作 B+的插入和删除操作仅需修改叶子节点和对应的索引节点,且由于非叶子节点不存储数据,因此插入和删除操作不会影响到整个的结构,分裂和合并操作也相对高效[^3]。 分块查找的插入和删除操作则较为复杂。插入时,若某个块已满,则需要进行块的分裂;删除时,若某个块中的元素过少,则可能需要进行块的合并。这些操作可能导致索引表的频繁更新,影响整体性能[^2]。 #### 应用场景 B+广泛应用于数据库和文件系统中,特别是在需要高效支持范围查询和顺序访问的场景下。由于其良好的缓存命中率和高效的插入删除操作,B+在大规模数据管理中表现出色[^3]。 分块查找则更适合于内存较小或数据量不大的场景,尤其是在数据分布较为均匀的情况下。它的实现相对简单,适合对性能要求不高的应用。 #### 示例代码 以下是一个简单的B+节点类的Python实现,展示了B+的基本结构: ```python class BPlusTreeNode: def __init__(self, is_leaf=False): self.keys = [] # 存储关键字 self.children = [] # 存储子节点 self.is_leaf = is_leaf # 是否为叶子节点 self.next = None # 仅叶子节点使用,指向下一个叶子节点 def insert(self, key): # 插入关键字的逻辑 pass def split(self): # 分裂节点的逻辑 pass ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值