码迷,mamicode.com
首页 > 编程语言 > 详细

二叉树,二叉排序树,红黑树 学习

时间:2018-01-15 22:29:29      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:detail   操作   archive   tail   rb-tree   引入   时间   中序   理解   

  二叉排序树是一种比较有用的折衷方案。  
  数组的搜索比较方便,可以直接用下标,但删除或者插入某些元素就比较麻烦。  
  链表与之相反,删除和插入元素很快,但查找很慢。  
  二叉排序树就既有链表的好处,也有数组的好处。  
  在处理大批量的动态的数据是比较有用。

 

二叉树数据结构:

typedef struct _BiTNode  
{  
    int data;  
    _BiTNode *leftChild;  
    _BiTNode *rightChild;  
}BiTNode, *pBiTree;

二叉树的创建和遍历:http://blog.csdn.net/pony_maggie/article/details/38390513

 

 

 

=======================================================================

二叉排序树

http://www.cnblogs.com/zhuyf87/archive/2012/11/09/2763113.html

数据结构同上,规定如下:

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

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

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

技术分享图片

中序遍历(左中右)二叉排序树可得到一个依据关键字的有序序列

搜索、插入、删除的时间复杂度等于树高,期望O(logn),最坏O(n)(数列有序,树退化成线性表,如右斜树)。

虽然二叉排序树的最坏效率是O(n),但它支持动态查找,且有很多改进版的二叉排序树可以使树高为O(logn),如平衡二叉树AVL、红黑树等。

 

 

 

 

 =======================================================================

平衡二叉树AVL(建立在二叉排序树之上!)

http://www.cnblogs.com/fornever/archive/2011/11/15/2249492.html

平衡二叉树定义(AVL):

它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

平衡因子(bf):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1;

 

要理解,如图两个节点之间的变换,可以继续保持平衡二叉树的规则!

节点1和节点2,1可以作为2的左孩子,2可以作为1的右孩子。

同理,3可以作为2的右孩子,2可以作为3的左孩子。

技术分享图片

 

 

 

插入:

最小不平衡子树的根结点:也就是当你进行插入操作时,找到该需要插入结点的位置并插入后,从该结点起向上寻找(回溯),第一个不平衡的结点即平衡因子bf变为-2或2。

为什么要引入这个最小不平衡根结点的概念,因为在插入时,该子树进行保持平衡操作后,其它的结点的平衡因子不会变,也就是整棵树又恢复平衡了。

为什么呢?

看图理解不平衡子树的旋转方式:

y是插入的节点,x是最小不平衡子树的根。

插入部位在左左

技术分享图片

第一种情况,瞬间秒懂,因为我上边说了那个变换规则。

第二种情况,a和x变换,d变成x的左孩子。(因为肯定是二叉排序树,x左子树的所有节点都比x小!)

变换的意思是,节点A要覆盖储存节点X的那块内存上,

变换过程:

变换的节点,要连带着各自的子树。如图2,

变换时,节点X带着自己的子节点B,节点A则带着自己的子节点-c-y和-d。即

技术分享图片

 

变换后,发现节点a有三个子树了,擦,给多出来的d找个合适的位置(按大小找到位置),安置一下。

 

右右

技术分享图片

 

左右

技术分享图片

要经过两次变换的。

 

右左

 技术分享图片

那么如何找到最小不平衡子树的根结点x,并判断出它是属于那种情况的?

看原博文吧,这里不管代码实现。

可以在判定了之后,调用keepBalance函数,使二叉树保持平衡。

 

原文中有 删除 和 插入。

 

 

 

 

 

 

 

=======================================================================

 红黑树

1. 如果插入一个node引起了树的不平衡,AVL和RB-Tree都是最多只需要2次旋转操作,即两者都是O(1);
但是在删除node引起树的不平衡时,最坏情况下,AVL需要维护从被删node到root这条路径上所有node的平衡性,因此需要旋转的量级O(logN),而RB-Tree最多只需3次旋转,只需要O(1)的复杂度。

2. 其次,AVL的结构相较RB-Tree来说更为平衡,
在插入和删除node更容易引起Tree的unbalance,因此在大量数据需要插入或者删除时,AVL需要rebalance的频率会更高。
因此,RB-Tree在需要大量插入和删除node的场景下,效率更高。
自然,由于AVL高度平衡,因此AVL的search效率更高。

作者:Acjx
链接:http://www.zhihu.com/question/20545708/answer/58717264

 

 红黑树(一)之 原理和算法详细介绍

 红黑树(二)之 C语言的实现

 红黑树(三)之 Linux内核中红黑树的经典实现

 

 

 

 

 

 

 

 

 

二叉树,二叉排序树,红黑树 学习

标签:detail   操作   archive   tail   rb-tree   引入   时间   中序   理解   

原文地址:https://www.cnblogs.com/WMCH/p/8289565.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!