B树和B+树

B-tree是一种自平衡数据结构,它能对数据进行排序,并允许在对数时间内进行搜索、顺序访问、插入和删除。B-tree是二叉搜索树的推广,一个节点可以有两个以上的子节点。与自平衡的二叉搜索树不同,b-tree对读取和写入大数据块的系统进行了优化。b树是外部内存数据结构的例子。通常用于数据库和文件系统。

B-tree的时间复杂度
算法
平均
最坏情况
Space
O(n)
O(n)
Search
O(log n)
O(log n)
Insert
O(log n)
O(log n)
Delete
O(log n)
O(log n)
        在b树中,内部(非叶节点)节点可以在某个预定义范围内拥有可变数量的子节点。当从节点插入或删除数据时,它的子节点数量会发生变化。为了维护预定义的范围,可以将内部节点加入或拆分。因为允许有一系列子节点,所以b树不需要像其他自平衡搜索树那样频繁地重新平衡,但是可能会浪费一些空间,因为节点并不是完全满的。子节点数量的下界和上界通常用于特定的实现。例如,在2-3个B-t中。
       b树的每个内部节点包含许多键。键的作用是分隔其子树的分离值。例如,如果一个内部节点有3个子节点(或子树),那么它必须有2个键:a1和a2。最左边的子树的所有值都小于a1,中间子树的所有值都在a1和a2之间,而最右边的子树的所有值都大于a2。

定义

根据Knuth的定义,m阶的b树是满足以下属性的树:
    1、每个结点最多有m个孩子。
    2、除根结点外,其他每个结点至少⌈m / 2⌉孩子。
    3、如果不是叶节点,根至少有两个子节点。
    4、有k个子结点的非根结点恰好包含k-1个关键码。
    5、所有的叶子都在同一层。


B-Tree的操作

Search
搜索类似于搜索二叉搜索树。从根节点开始,树被递归地从上到下遍历。在每一层上,搜索将缩小到范围包括搜索值的指针(子树)。子树的范围由其父节点中包含的值或键定义。这些限制值也称为分离值。

Insertion
所有的插入从一个叶节点开始。要插入一个新元素,搜索树以找到要添加新元素的叶子节点。将新元素插入到该节点中,步骤如下:
1、如果节点包含的元素个数小于最大允许数量,那么就有新元素的空间。在节点中插入新元素,保持节点元素的有序。
2、否则节点是满的,将其均匀地分成两个节点:
1)从叶的元素和新元素中选择一个中值。
2)小于中值的值放在新左节点中,大于中值的值放在新的右节点中,中间值作为分离值。
3)分离值被插入到节点的父节点中,这可能导致它被拆分,等等。如果节点没有父节点(即,节点是根节点),在此节点之上创建一个新根(增加树的高度)。


一个以迭代方式的B树插入示例。这个B树的节点最多有3个孩子(Knuth order 3)。

Deletion
从b树中删除有两种流行的策略。
1、找到并删除该项目,然后重新构造树以保留其不变量。
2、对树进行单次传递,但在进入(访问)节点之前,对树进行结构调整,以便在遇到要删除的键时,可以删除它,而不需要进行任何进一步的重构。


B+树

B+树是一个N-ary树,每个节点有一个变量,但通常有大量的子节点。B+树由根、内节点和叶组成。根可以是叶结点,也可以是有两个或两个以上子结点的结点。
B+树可以被看作是B树,其中每个节点只包含键(不是键值对),并且在底部添加一个与叶子相连接的额外的层。
B+树的主要价值是存储数据,以便在面向块的存储环境中高效检索——特别是文件系统。这主要是因为与二叉搜索树不同的是,B+树有非常高的fanout(在一个节点中指向子节点的指针数量,[1]通常是在100或以上),这减少了在树中查找元素所需的I/O操作的数量。
ReiserFS、NSS、XFS、JFS、ReFS和BFS文件系统都使用这种类型的树进行元数据索引;BFS还使用B+树来存储目录。NTFS使用B+树进行目录和安全相关的元数据索引。EXT4使用范围树(修改后的B+树数据结构)用于文件范围索引。关系数据库管理系统,如IBM DB2、Informix、Microsoft SQL Server、Oracle 8、Sybase ASE、和SQLite支持这类树的表索引。键值数据库管理系统,如CouchDB和Tokyo Cabinet支持这种类型的树。

一个简单的B+树示例,将键1-7与数据值d1-d7连接。链表(红色)允许快速的顺序遍历。这棵树的分支因子是=4。

定义
B+树是应文件系统所需而出的一种B树的变型树。一棵m阶的B+树和m阶的B-树的差异在于:
    1、有n棵子树的结点中含有n个关键字,每个关键字不保存数据,只用来索引,所有数据都保存在叶子节点。
    2、所有的叶子结点中包含了全部关键字的信息,及指向含这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大顺序链接。
    3、所有的非终端结点可以看成是索引部分,结点中仅含其子树(根结点)中的最大(或最小)关键字。
通常在B+树上有两个头指针,一个指向根结点,一个指向关键字最小的叶子结点。

主要操作
Search
B+树的根表示树中所有的值范围,其中每个内部节点都是子区间。
我们在B+树中寻找一个值k。从根开始,我们寻找可能包含k值的叶子。在每个节点上,我们都知道应该遵循哪个内部指针。内部B +树节点最多 d d≤ B孩子,他们每个人都代表一个不同的sub-interval的地方。我们通过搜索节点的键值来选择相应的节点。
Function: search (k)
  	return tree_search (k, root);
 
Function: tree_search (k, node)
  	if node is a leaf then
    		return node;
 	switch k do
  	case k < k_0
    		return tree_search(k, p_0);
  	case k_i ≤ k < k_{i+1}
    		return tree_search(k, p_{i+1});
  	case k_d ≤ k
    		return tree_search(k, p_{d+1});

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/GUI1259802368/article/details/79944920
个人分类: 数据结构
所属专栏: 经典数据结构
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭