zoukankan      html  css  js  c++  java
  • 二叉树,二叉排序树,红黑树 学习

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

    二叉树数据结构:

    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内核中红黑树的经典实现

    联我:shen5773384##163.com
  • 相关阅读:
    543. Diameter of Binary Tree【Easy】【二叉树的直径】
    114. Flatten Binary Tree to Linked List【Medium】【将给定的二叉树转化为“只有右孩子节点”的链表(树)】
    Java实现蛇形矩阵
    215. Kth Largest Element in an Array【Medium】【找到第 k 大的元素】
    524. Longest Word in Dictionary through Deleting【Medium】【删除后得到的字典中的最长单词】
    141. Linked List Cycle【Easy】【判断链表是否存在环】
    88. Merge Sorted Array【Easy】【双指针-不用额外空间归并两个有序数组】
    680. Valid Palindrome II【Easy】【双指针-可以删除一个字符,判断是否能构成回文字符串】
    345. Reverse Vowels of a String【Easy】【双指针-反转字符串中的元音字符】
    633. Sum of Square Numbers【Easy】【双指针-是否存在两个数的平方和等于给定目标值】
  • 原文地址:https://www.cnblogs.com/WMCH/p/8289565.html
Copyright © 2011-2022 走看看