(一)树(树、二叉树、满二叉树、完全二叉树、二叉搜索树、二叉平衡树、B-Tree、B+Tree)

1.树

1.概念

树结构简单来说,就是数据元素之间具有层次关系的非线性结构。它是从自然界中的树抽象而来的,有树根、从树根发源类似枝杈的分支关系以及作为分支重点的叶子等。下面我们给出树结构的完整定义:
树(tree)是由n(n ≥0)个节点组成的有限集合。n=0的树称为空树;n >0 的树T的特点如下:

  • 有一个特殊的节点称为根节点(root),它只有直接后继节点,没有直接前驱节点。
  • 当n ≥1时,除根节点之外的其他节点分为m(m≥0)个互不相交的集合T1,T2,···,Tm,每个集合Tm(1≤i≤m)本身又是一棵结构与树类同的子树。每棵子树的根节点有且仅有一个直接前驱节点,但可以有零或多个直接后继节点。
    在这里插入图片描述

2.相关术语

  • 节点:节点(node)由数据元素(关键字)以及指向子树的地址(指针)构成;
  • 孩子节点与双亲节点:若X节点有子树,则子树的根节点称为X的孩子(child)节点,也称子女节点;相应地,X称为其孩子的双亲(parents)节点,也称为父母节点。一棵树中,根没有双亲节点;
  • 兄弟节点:同一双亲的孩子节点之间互称兄弟(sibling)节点;
  • 祖先节点与后台节点:X节点的祖先(ancestor)是指从根到X所经过的所有节点;X节点的后代(descendant)是指Xj节点的所有孩子节点,以及孩子节点的孩子;
  • 节点的度:节点的度(degree)定义为节点节点所拥有子树的棵树。
  • 叶子节点与分支节点:叶子(leaf)节点是指节点的度为0的节点,又称为终端节点。除叶子节点之外的其他节点,称为分支节点或非页节点;
  • 树的度:树的度是指树种各节点度的最大值;
  • 树的深度或高度:树种节点的最大层次数称为树的高度(depth)或高度(height);
  • 无序树与有序树:由树的定义可知,若节点的子树T0,T1,…之间没有次序,称为无序树;如果树中节点的子树T0,T1,…从左至右是有次序的(即不能交换),则称该树为有序树(orderd tree).

2.二叉树

1.概念

二叉树(binary tree)是n(n≥0)个节点组成的有限集合,n=0时称为空二叉树;n>0时,二叉树由一个根节点和两棵互不相交的、分别被称为左子树和右子树的子二叉树构成。
二叉树是一种有序(不一定是什么顺序,或者叫做次序、排列等)树,因为二叉树中每个节点的两棵树有左、右之分,即使只有一个子树,也要区分是左子树还是右子树。
在这里插入图片描述
如上图所示,如果把他看成是普通的树结构,则图(a)和(b)表示同一棵树;如果看成是二叉树结构,则(a)和(b)表示两棵不同的二叉树。
二叉树的节点最多有两棵树,所以二叉树的度最多为。

2.二叉树的基本形态

二叉树有5钟基本形态,如下图所示:
在这里插入图片描述

3.二叉树的性质

  • 若根节点的层次为1,则二叉树第i层的节点数目最多为 2 i − 1 2^{i-1} 2i1(i≥1)个;
  • 在深度为k的二叉树中,至多有 2 k − 1 2^{k-1} 2k1个节点(k≥0);在这里插入图片描述
  • 满二叉树(full binary tree):一个深度k的且具有 2 k 2^{k} 2k -1(k≥0)个节点的二叉树称为满二叉树,即每一层的节点数目都达到最大值。在这里插入图片描述
  • 完全二叉树(complete binary tree):一棵具有n个节点深度为k的二叉树,如果它的每一个节点都与深度为k的满二叉树中编号为1~n的节点一一对应,则称这棵二叉树为完全二叉树。
    在这里插入图片描述

4.完全二叉树的特点

  • 满二叉树一定是完全二叉树,而完全二叉树不一定是满二叉树。完成二叉树只有最下面一层可以不满,其上各层都可以看成满二叉树;
  • 完全二叉树是具有二叉树结构的而不一定满的二叉树;
  • 完全二叉树至多只有最下面两层节点的度可以小于2;
  • 完全二叉树最下面一层的节点都集中在该层最左边位置上,如下图就不是完全二叉树
    在这里插入图片描述

5.二叉树的遍历

遍历二叉树就是按照一定的规则和次序访问二叉树中的所有节点,并且每个节点仅被访问一次。若规定对子树的访问按“先左后右”的次数进行,则遍历二叉树有3种次序:

  • 先根次序:访问根节点,遍历左子树,遍历右子树
  • 中根次序:遍历左子树,遍历根节点,遍历右子树
  • 后根次序:遍历左子树,遍历右子树,遍历根节点
    关于二叉树遍历的代码实现,请查看博客二叉树的三种遍历方式(JAVA版)

3.二叉搜索树

1.概念

二叉搜索树,又称二叉排序树(Binary Search Tree,Binary Sort Tree),二叉搜索树或为空树;或者是这样一棵二叉树,若左子树不为空,则左子树上所有节点元素的值均小于根节点,若右子树不为空,则右子树上所有节点元素的值的均大于根节点,其左、右子树也是二叉搜索树。这一规则适用于二叉查找树中的每一个节点。二叉搜索树的时间复杂度为O(log(n))。如下图所示:在这里插入图片描述
在这里插入图片描述

2.二叉搜索树操作

关于二叉搜索的构建、遍历及删除等树的操作,请查看上一篇博客《二叉搜索树的构建、遍历及删除(JAVA版)》

4.二叉平衡树(AVL树)

1.概念

平衡二叉树(Balanced Binary Tree)是二叉搜索树的一个进化体,是1962年,G.M. Adelson-Velsky 和 E.M. Landis发明了这棵树,所以它又叫AVL树。
平衡二叉树,指的是若左子树不为空,则左子树上所有节点元素的值均小于根节点,若右子树不为空,则右子树上所有节点元素的值的均大于根节点,这一规则适用于二叉查找树中的每一个节点(其实这就是说二叉平衡树首先它是一棵二叉搜索树),且左子树与右子树的高度差最大为1

2.为什么要产生二叉平衡树

通过上面的学习我们知道,二叉搜索树就可以让我们的查询变的高效了,不需要从头遍历整棵树上的所有节点,只需要根据当前值与节点值得比对,就可以直接确定下一步的方向,每次比较,都会把搜索范围缩小,类似于二分法。那么既然二叉搜索树的效率已经很高了,为什么要因为二叉平衡树呢?其实这就是二叉搜索树有个缺点,这个缺点我们通过下面的图来看一下:
在这里插入图片描述
上面b和竟然变成了链表,同时树的深度也增加了很多,也就是,左、右子树分布极为不平衡。也就是说,插入的序列越接近有序,生成的二叉搜索树就越像是一个链表。为了避免这种情况的发生,即让树的结构看起来尽量“均匀”,左右子树的节点数尽量一样多。

3.二叉平衡树的特点

  1. 非叶子节点最多拥有两个节点;
  2. 非叶子节点元素的值
  3. 树的左右两边的层数相差不会大于1;

5.B树(B-Tree)

1.概念

B树也称B-树,它是一棵多路平衡查找树(查找路径不只两个),它其实是从平衡二叉树变化而来的。B树中所有节点的孩子节点数的最大值称为B树的阶。一棵m阶B树的或为空树,或为满足如下特性的m叉树:

  1. 树中每个节点最多有m棵子树(即至少有m-1个关键字);–特指非叶子节点(终端节点)
  2. 若根节点不是终端节点,则至少有两棵子树;
  3. 除根节点外的所有非叶子节点至少有[m/2](取上界ceiling)棵子树(即最少有[m/2]-1个关键字);
  4. 非叶节点中的信息包括[n,P0,K1,P1,K2,P2,…,Kn,Pn],其中n表示该节点中保存的关键字个数,K为关键字且Ki<Ki+1,Pi为指向子树根节点的指针。并且P(i-1)所指的子树中所有节点的均小于Ki;
  5. 所有节点关键字是按递增次序排列,并遵循左小右大原则;–特指非叶子节点(终端节点)
  6. 叶子节点的的特征:叶子节在相同的层,并且这些节点不带信息(不带指针和关键字),实际上这些节点就表示找不到指定的值,也就是指向这些节点的指针为空。在这里插入图片描述

2.B树的高度

我们假设:n个关键字,阶数为m,高度为h的B树,那么它的高度满足什么的范围呢?
首先,第一层的节点数:1
第二层的节点数:m
第三层的节点数:m*m= m 2 m^{2} m2
.
.
第h层的节点数: m h − 1 m^{h-1} mh1
而B树中每个节点最多有m-1个关键字,
所以关键字的个数n满足一下条件:
n≤(m-1)(1+m+ m 2 m^{2} m2+…+ m h − 1 m^{h-1} mh1) = m h m^{h} mh -1
计算可得: l o g m ( n + 1 ) log_{m}(n+1) logm(n+1) ≤h
其次,B树第h层最少的关键字数量满足:
2 ( m / 2 ) h (m/2)^{h} (m/2)h≤n+1
所以我们得出:
l o g m ( n + 1 ) log_{m}(n+1) logm(n+1) ≤h≤ l o g m / 2 ( ( n + 1 ) / 2 ) log_{m/2}((n+1)/2) logm/2((n+1)/2)+1
从上面的公式我们可以看出,m(阶数)对于树的高度有决定性的影响。因此如果每个节点包含更多的元素个数,在元素个数相同的情况下,则更有可能减少B树的高度。

3.B树的查询流程

假如有下面一棵B树,我们要查找24,
在这里插入图片描述

  1. 获取根节点的关键字进行比较,当前根节点关键字为21和35,21<24<35,所以找到指向21和35中间的子节点(二分法规则,左小右大,左边放小于当前节点值的子节点、右边放大于当前节点值的子节点);
  2. 拿到关键字26和33,24<26 所以直接找到左子节点;
  3. 拿到23和24,然后遍历,因为24=24 所以直接返回关键字和指针信息(如果树结构里面没有包含所要查找的节点则返回null);

4.B树与二叉平衡树的比较

我们知道,B 树是为了磁盘或其它存储设备而设计的一种多叉平衡查找树,它在降低磁盘I/0操作方面要更好一些,而磁盘的IO非常慢,降低磁盘的IO,那么查找的速度就会明显提高,那与平衡二叉树来比较,它又有怎么样的提高呢?
从上面3中我们查找24来看,只需要进行3次的IO操作就可以查找出24来,如果是平衡二叉树呢?显然树的高度会高很多,IO的次数也会增多。
所以,B树相对于平衡二叉树的不同是,每个节点包含的关键字增多了,特别是在B树应用到数据库中的时候,数据库充分利用了磁盘块的原理(磁盘数据存储是采用块的形式存储的,每个块的大小为4K,每次IO进行数据读取时,同一个磁盘块的数据可以一次性读取出来)把节点大小限制为能充分使用在磁盘块大小范围;把树的节点关键字增多后树的层级比原来的二叉树少了,减少数据查找的次数和复杂度;

6.B+树(B+Tree)

1.概念

B+Tree是由B-Tree改进而来,在这里我们不给出具体的定义了,只说一下它的特点(与B-Tree相比):
一棵m阶的B+树和m阶的B树的差异在于:

  1. 有n棵子树的结点中含有n个关键字; (而B 树是n棵子树有n-1个关键字);
  2. 所有的叶子结点中包含了全部关键字的信息(即包含所有的索引值),及指向含有这些关键字记录的指针,且叶子结点本身依关键字的大小自小而大的顺序链接。 (而B 树的叶子节点并没有包括全部需要查找的信息);
  3. 所有的非终端结点可以看成是索引部分,结点中仅含有其子树根结点中最大(或最小)关键字。 (而B 树的非终节点也包含需要查找的有效信息)
    在这里插入图片描述

2.B+树的优点(对比B-Tree)

  1. B+树的层级更少:相较于B-Tree,B+每个非叶子节点不需要存储全部索引,只需要存索引近可以了,所以存储的关键字数更多,树的层级更少,B+树的结构B-Tree更加的“矮胖”,IO次数就更少了,比所以查询数据更快;
  2. B+树查询速度更稳定:B+所有关键字数据地址都存在叶子节点上,所以每次查找的次数都相同,而B-Tree只要匹配到要查找的元素即可,无论匹配元素的位置处在哪个非叶子节点,所以查询速度要比B-Tree更稳定;
  3. B+树天然具备排序功能:B+树所有的叶子节点数据构成了一个有序链表,在查询大小区间的数据时候更方便,数据紧密性很高,缓存的命中率也会比B-Tree高。
  4. B+树全节点遍历更快:B+树遍历整棵树只需要遍历所有的叶子节点即可,,而不需要像B-Tree一样需要对每一层进行遍历,这有利于数据库做全表扫描。

注意:B-Tree其实有时候也并不B+树差,如果经常访问的数据离根节点很近,而B树的非叶子节点本身存有关键字其数据的地址,所以这种数据检索的时候会要比B+树快。

6.总结

到此为止,关于这几种树就介绍完了,里面可能有一些理解不对的地方,欢迎大家指正。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值