数据结构:二叉树、平衡二叉树、红黑树的原理差异和性能分析

树是数据结构中的重中之重,尤其以各类二叉树又是其中的难点,二叉树种类繁多实现各异,我们主要讲常见的二叉树。

1、二叉树

二叉树是指树的度为2的一种树。

满二叉树:在一棵二叉树中,当第i层的节点个数为2^(i-1)时称此层是满的,当树中每一层都是满的时称此树是满二叉树。

完全二叉树:在一棵树中,除最后一层外,若其余层都是满的,并且最后一层或是满的,或是在最右侧缺少连续若干个节点。此时该树称为完全二叉树。

理想二叉树:在一棵树中,除最后一层外,若其余层都是满的,最后的节点可以任意分布,此时该树称为理想二叉树。

根据上面的定义可得下图关系:

                                          

二叉树有如下几条性质:

      1、在二叉树的第i层上至多有2i-1个结点

      2、深度为k的二叉树至多有2k-1个结点(k>=1)

       3、对任何一棵二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0=n2+1

      4、具有n个结点的完全二叉树的深度为「log2n」+1

       5、如果对一棵有n个结点的完全二叉树(其深度为「log2n」+1)的结点按层序编号(从第1层到第「log2n」+1层,每层从左到右),则对任一结点i(1≤i≤n),有 :

                 如果i=1,则结点i是二叉树的根,无双亲;如果i>1,则其双亲PARENT(i)是结点「i/2」 

                 如果2i>n,则结点n无左孩子(结点i为叶子结点);否则其左孩子LCHILD(i)是结点2i

                 如果2i+1>n,则结点i无右孩子,否则其右孩子RCHILD(i)是结点2i+1 

在二叉树的遍历中根据根节点的遍历的顺序将遍历分为前序遍历,中序遍历,后序遍历三种。

前序遍历:根节点-->左子树--->右子树

中序遍历:左子树--->根节点--->右子树

后序遍历:左子树--->右子树--->根节点

这里要注意,数的遍历都是递归调用。

2、二叉排序树

排序二叉树是一种特殊结构的二叉树,可以非常方便地对树中所有节点进行排序和检索。

排序二叉树要么是一棵空二叉树,要么是具有下列性质的二叉树:

       1、若它的左子树不空,则左子树上所有节点的值均小于它的根节点的值;

       2、若它的右子树不空,则右子树上所有节点的值均大于它的根节点的值;

       3、它的左、右子树也分别为排序二叉树。

 (1)、查找时间复杂度

任何一个数据的查找过程都需要从根结点出发,沿某一个路径朝叶子结点前进。因此查找中数据比较次数与树的形态密切相关。

当树中每个结点左右子树高度大致相同时,树高为logN。则平均查找长度与logN成正比,查找的平均时间复杂度在O(logN)数量级上。

当先后插入的关键字有序时,BST退化成单支树结构。此时树高n。平均查找长度为(n+1)/2,查找的平均时间复杂度在O(N)数量级上。

(2)、插入时间复杂度

新结点插入到树的叶子上,完全不需要改变树中原有结点的组织结构。插入一个结点的代价与查找一个不存在的数据的代价完全相同。

(3)、删除时间复杂度 

当删除一个结点P,首先需要定位到这个结点P,这个过程需要一个查找的代价。然后稍微改变一下树的形态。如果被删除结点的左、右子树只有一个存在,则改变形态的代价仅为O(1)。如果被删除结点的左、右子树均存在,只需要将当P的左孩子的右孩子的右孩子的…的右叶子结点与P互换,在改变一些左右子树即可。因此删除操作的时间复杂度最大不会超过O(logN)。

 3、平衡二叉树(AVL)

为了解决二叉查找树在最差情况下竟然和顺序查找效率相当的问题,G.M. Adelson-Velsky和E.M. Landis提出了平衡二叉树,也叫做AVL树。平衡二叉树的特点是:树中任何节点的两个子树的高度最大差别为1。

(1)、查找时间复杂度

AVL是严格平衡的。因此查找效率最好,最坏情况都是O(logN)数量级的。

(2)、插入时间复杂度

AVL必须要保证严格平衡,那么每一次插入数据使得AVL中某些结点的左右子树高度差超过1就必须进行旋转操作。事实上,AVL的每一次插入结点操作最多只需要旋转1次(单旋转或双旋转)。因此,总体上插入操作的代价仍然在O(logN)级别上(插入结点需要首先查找插入的位置)。 

(3)、删除时间复杂度

AVL删除之后必须检查从删除结点开始到根结点路径上的所有结点的平衡因子。因此删除的代价稍微要大一些。每一次删除操作最多需要O(logN)次旋转。因此,删除操作的时间复杂度为O(logN)+O(logN)=O(2logN)

(4)、节点旋转

把二叉树中每个节点的左子树高度减去右子树高度的差定义为该节点的平衡因子。因此AVL树中每个节点的平衡因子只能是1、0、-1.当向树中插入一个新节点时,插入后某些节点的左右子树的高度如果不变就不会影响这些节点的平衡因子,如果左右子树的高度增加1就会破坏该节点的平衡因子,这里说的破坏平衡因子是指平衡因子不在合法范围内(1、0、-1)。出现这种情况后就需要调整该节点让平衡因子重回合法范围。为了方便讨论,我们用A来表示根节点,分成4中情况讨论:

LL型调整:

在A节点的的左子树的左子树上插入节点,使得A节点的平衡因子由1变成2:

          

LR型调整:

在A节点的的左子树的右子树上插入节点,使得A节点的平衡因子由1变成2:

RR型调整:

在A节点的的右子树的右子树上插入节点,使得A节点的平衡因子由-1变成-2:

                                                                                                                                                                     

RL型调整:

在A节点的的右子树的左子树上插入节点,使得A节点的平衡因子由-1变成-2:

4、红黑树(RBTree)

 

二叉平衡树的严格平衡策略以牺牲建立查找结构(插入,删除操作)的代价,换来了稳定的O(logN) 的查找时间复杂度。为了解决平衡和时间复杂度的问题,Rudolf Bayer提出了红黑树,红黑树不追求"完全平衡",即不像AVL那样要求节点的 |balFact| <= 1,它只要求部分达到平衡以此来折中节点平衡和查找的复杂度。

红黑树必须满足的五点约束:

       1、节点是红色或黑色。

       2、根是黑色。

      3、所有叶子都是黑色(叶子是NIL节点)。

     4、每个红色节点必须有两个黑色的子节点。(从每个叶子到根的所有路径上不能有两个连续的红色节点。)

     5、从任一节点到其每个叶子的所有简单路径都包含相同数目的黑色节点(简称黑高)。

(1)、红黑树再平衡

插入节点是红色,首先分析如果它的父亲为黑,那么直接插入,如果他的父亲为红那么在该路径上面开始分情况调整,具体的调整过程可以分为三个情况:
1、父节点是红色,叔叔节点也是红色:

2、父节点是左子树红色,叔叔节点不存在或者是是黑色:

新插入节点是左孩子:

                                  

新插入节点是右孩子:

                                  

3、父节点是右子树红色,叔叔节点不存在或者是是黑色:

 新插入节点是左孩子:

                                                     

新插入节点是右孩子:

                               

(2)、查找时间复杂度

由于红黑树的性质(最长路径长度不超过最短路径长度的2倍),可以说明红黑树虽然不像AVL一样是严格平衡的,但平衡性能还是要比BST要好。其查找代价基本维持在O(logN)左右,但在最差情况下(最长路径是最短路径的2倍少1),比AVL要略逊色一点。

(3)、插入时间复杂度

RBT插入结点时,需要旋转操作和变色操作。但由于只需要保证RBT基本平衡就可以了。因此插入结点最多只需要2次旋转,这一点和AVL的插入操作一样。虽然变色操作需要O(logN),但是变色操作十分简单,代价很小。

(4)、删除时间复杂度

RBT的删除操作代价要比AVL要好的多,删除一个结点最多只需要3次旋转操作

红黑是用非严格的平衡来换取增删节点时候旋转次数的降低,任何不平衡都会在三次旋转之内解决,而AVL是严格平衡树,因此在增加或者删除节点的时候,根据不同情况,旋转的次数比红黑树要多。

就插入节点导致树失衡的情况,AVL和RB-Tree都是最多两次树旋转来实现恢复平衡,旋转的量级是O(1)

删除节点导致失衡,AVL需要维护从被删除节点到根节点root这条路径上所有节点的平衡,旋转的量级为O(logN),而RB-Tree最多只需要旋转3次实现恢复平衡,只需O(1),所以说RB-Tree删除节点更快。

AVL的结构相较于RB-Tree更为平衡,也就是说红黑树的查询性能比相同内容的AVL树最多多一次比较,因此AVL的Search效率更高。

总体来说,RB-Tree的统计性能高于AVL.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 二叉树是一种树形数据结构,它由一个根节点和最多两个子树组成,这两个子树被称为左子树和右子树。二叉树中的每个节点最多有两个子节点,如果一个节点只有一个子节点,那么这个子节点必须是左子节点。 二叉树有很多种类型,最基本的二叉树是二叉搜索树。在二叉搜索树中,左子树的所有节点的值都小于根节点的值,右子树的所有节点的值都大于根节点的值。这使得在二叉搜索树中进行查找、插入和删除操作非常高效。 除了二叉搜索树,还有平衡二叉树红黑树、B树等多种二叉树类型,每种类型的二叉树都有其特定的应用场景和优缺点。 二叉树的遍历方式有三种:前序遍历(先访问根节点,然后遍历左子树和右子树)、中序遍历(先遍历左子树,然后访问根节点,最后遍历右子树)和后序遍历(先遍历左子树和右子树,最后访问根节点)。二叉树的遍历方式是解决很多问题的基础,比如查找二叉树中的最大值、计算二叉树的深度等。 ### 回答2: 二叉树是一种重要的数据结构,它由一组称为节点的元素组成,每个节点最多可以连接到两个子节点,分别称为左子节点和右子节点。二叉树的一个节点可以表示一个值或者一条数据。 二叉树具有以下特点: 1. 根节点:二叉树的顶部节点称为根节点,它是整个树的起点。 2. 叶子节点:没有子节点的节点称为叶子节点,它们位于树的末端。 3. 分支节点:有子节点的节点称为分支节点,它们是树的中间节点。 4. 子树:以某个节点为根节点,将其及其后代节点组成的树称为子树。 5. 左子树和右子树:一个节点的左右子节点分别构成左子树和右子树。 6. 高度:树中节点的最大层次称为树的高度。 二叉树有多种变种,如满二叉树、完全二叉树等。满二叉树是一种每个节点都有两个子节点的二叉树,而完全二叉树是一种除了最后一层外,其他层都是满的二叉树二叉树的应用十分广泛,常见的应用场景包括文件系统、数据库索引等。在二叉树中,插入、删除、查找等操作效率很高,时间复杂度通常为O(logN)。然而,如果二叉树退化成链表,操作效率会大大降低,时间复杂度为O(N)。 总的来说,二叉树是一种简单但十分重要的数据结构。它能够高效地存储、操作数据,被广泛应用于各个领域。 ### 回答3: 二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点。 二叉树的特点是左子节点小于父节点,而右子节点大于父节点,这样的特性方便在树中进行排序和搜索操作。 二叉树有多种常见的类型,包括满二叉树、完全二叉树平衡二叉树等。 满二叉树是指除了叶子节点外,每个节点都有两个子节点的二叉树。 完全二叉树是指除了最后一层以外的其他层都是满的,最后一层的节点从左到右依次填满。 平衡二叉树是指左子树和右子树的高度差不超过1的二叉树,这样可以保证在最坏情况下的搜索时间复杂度为O(logn)。 二叉树可以使用数组或链表实现,具体选择取决于应用场景和需求。 在二叉树中,我们可以使用递归或迭代的方式进行遍历操作,包括先序遍历、中序遍历和后序遍历。 先序遍历是指先访问根节点,然后递归遍历左子树和右子树。 中序遍历是指先递归遍历左子树,然后访问根节点,最后递归遍历右子树。 后序遍历是指先递归遍历左子树和右子树,然后访问根节点。 二叉树还可以进行插入、删除和查找操作。插入操作一般按照二叉搜索树的规则进行,即比根节点小的值插入左子树,比根节点大的值插入右子树。删除操作需要考虑不同情况,包括删除叶子节点、删除有一个子节点的节点和删除有两个子节点的节点。查找操作可以根据二叉搜索树的性质进行递归或迭代实现。 总之,二叉树是一种常见且重要的数据结构,能够方便地进行排序、搜索和插入等操作,同时还有多种类型和遍历方式供选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值