数据结构中关于树的总结

前言

一直对数据结构中的各种树没有分清楚,最近下决心学习总结下来。
首先需要了解二叉树,满二叉树,完全二叉树等概念,这些在本文不做赘述。

二叉排序树

又名二叉搜索树/二叉查找树。它的特性是:

  • 若左子树不空,则左子树上所有结点的值均小于它的根结点的值;
  • 若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值;
  • 左、右子树也分别为二叉排序树;

二叉查找树的性质

对二叉查找树进行中序遍历,即可得到有序的数列。

时间复杂度

它和二分查找一样,插入和查找的时间复杂度均为O(logn),但是在最坏的情况下仍然会有O(n)的时间复杂度。原因在于插入和删除元素的时候,树没有保持平衡。我们追求的是在最坏的情况下仍然有较好的时间复杂度,这就是平衡查找树设计的初衷。
二叉查找树的高度决定了二叉查找树的查找效率。

AVL树

  • 要么是棵空树,要么其根节点左右子树的深度之差的绝对值不超过1;
  • 其左右子树也都是平衡二叉树;

AVL树是最先发明的自平衡二叉查找树。包括两种旋转:

  • 单旋转
  • 双旋转

红黑树

另一种平衡二叉树

  • 节点是红色或者黑色
  • 根是黑色
  • 所有叶子节点都是黑色(叶子节点是NIL节点)
  • 每个红色节点必须有两个黑色的子节点。
  • 从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点。

基本操作

  • 左旋
  • 右旋

B树

B树也是一种用于查找的平衡树,但是它不是二叉树。
B树的定义:B树(B-tree)是一种树状数据结构,能够用来存储排序后的数据。这种数据结构能够让查找数据、循序存取、插入数据及删除的动作,都在对数时间内完成。B树,概括来说是一个一般化的二叉查找树,可以拥有多于2个子节点。与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。这种数据结构常被应用在数据库和文件系统的实作上。

在B树中查找给定关键字的方法是,首先把根结点取来,在根结点所包含的关键字K1,…,Kn查找给定的关键字(可用顺序查找或二分查找法),若找到等于给定值的关键字,则查找成功;否则,一定可以确定要查找的关键字在Ki与Ki+1之间,Pi为指向子树根节点的指针,此时取指针Pi所指的结点继续查找,直至找到,或指针Pi为空时查找失败。

B树作为一种多路搜索树(并不是二叉的):

1) 定义任意非叶子结点最多只有M个儿子;且M>2;

2) 根结点的儿子数为[2, M];

3) 除根结点以外的非叶子结点的儿子数为[M/2, M];

4) 每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)

5) 非叶子结点的关键字个数=指向儿子的指针个数-1;

6) 非叶子结点的关键字:K[1], K[2], …, K[M-1];且K[i] < K[i+1];

7) 非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;

8) 所有叶子结点位于同一层;

B+树

B+树是B-树的变体,也是一种多路搜索树:

  • 1.其定义基本与B-树同,除了:

  • 2.非叶子结点的子树指针与关键字个数相同;

  • 3.非叶子结点的子树指针P[i],指向关键字值属于[K[i], K[i+1])的子树

(B-树是开区间);

  • 5.为所有叶子结点增加一个链指针;
  • 6.所有关键字都在叶子结点出现;
    如:(M=3)

B+的搜索与B-树也基本相同,区别是B+树只有达到叶子结点才命中(B-树可以在

非叶子结点命中),其性能也等价于在关键字全集做一次二分查找;

B+的特性:

  • 1.所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好

是有序的;

  • 2.不可能在非叶子结点命中;

  • 3.非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储

(关键字)数据的数据层;

  • 4.更适合文件索引系统;

B*树

是B+树的变体,在B+树的非根和非叶子结点再增加指向兄弟的指针;

B*树定义了非叶子结点关键字个数至少为(2/3)*M,即块的最低使用率为2/3

(代替B+树的1/2);
B+树的分裂:当一个结点满时,分配一个新的结点,并将原结点中1/2的数据

复制到新结点,最后在父结点中增加新结点的指针;B+树的分裂只影响原结点和父

结点,而不会影响兄弟结点,所以它不需要指向兄弟的指针;
B*树的分裂:当一个结点满时,如果它的下一个兄弟结点未满,那么将一部分

数据移到兄弟结点中,再在原结点插入关键字,最后修改父结点中兄弟结点的关键字

(因为兄弟结点的关键字范围改变了);如果兄弟也满了,则在原结点与兄弟结点之

间增加新结点,并各复制1/3的数据到新结点,最后在父结点增加新结点的指针;
所以,B*树分配新结点的概率比B+树要低,空间使用率更高;

参考资料

猜你喜欢

转载自blog.csdn.net/iverson2010112228/article/details/87281114