zoukankan      html  css  js  c++  java
  • 平衡二叉树

    平衡因子(Balance Factor,简称BF):BF(T) = hL-HR,其中hL和HR分别为T的左、右子树的高度。

    平衡二叉树(Balanced Binary Tree)(AVL树):空树,或者任意结点左、右子树高度差的绝对值不超过1,即|BF(T)|≤1

    平衡二叉树的高度能到达log2N吗?

    设nh高度为h的平很二叉树的最少结点数。结点数最少时:nh=nh-1+nh-2+1

    斐波那契数列: F0=1,F1=1,Fi=Fi-1+Fi-2 for i>1


    平衡二叉树的调整

    • 不平衡的“发现者”是Mar,“麻烦结点”Nov在发现者右子树的右边,因而叫RR插入,需要RR旋转(右单旋)

    技术分享

    • “发现者”是Mar,“麻烦结点”Apr在发现者左子树的左边,因而叫LL插入,需要LL旋转(左单旋)

    技术分享

    • “发现者”是May,“麻烦结点”Jan在左子树的右边,因而叫LR插入,需要LR旋转

    技术分享

    • “麻烦结点”在右子树的左边,因而叫 RL 插入,需要RL 旋转

    技术分享

      1 typedef struct AVLNode *Position;
      2 typedef Position AVLTree;
      3 struct AVLNode {
      4     ElementType Data;   /* 结点数据 */
      5     AVLTree Left;
      6     AVLTree Right;
      7     int Height;         /* 树高 */
      8 };
      9 
     10 int Max(int a, int b)
     11 {
     12     return a>b?a:b;
     13 }
     14 
     15 int GetHeight(AVLTree A)
     16 {
     17     int MaxH, HR, HL;
     18     if(A) {
     19         HL = GetHeight(A->Left);
     20         HR = GetHeight(A->Right);
     21         MaxH = (HL>HR)?HL:HR;
     22         return MaxH+1;
     23     }
     24     return -1;          //如果树为空树高为-1,叶子结点为0
     25 }
     26 
     27 AVLTree SingleLeftRotation(AVLTree A)
     28 {
     29     /* 注意:A必须有一个左子结点B */
     30     /* 将A与B做左单旋,更新A与B的高度,返回新的根结点B */
     31     AVLTree B = A->Left;
     32     A->Left = B->Right;
     33     B->Right = A;
     34     A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
     35     B->Height = Max(GetHeight(B->Left), A->Height) + 1;
     36 
     37     return B;
     38 }
     39 
     40 AVLTree SingleRightRotation(AVLTree A)
     41 {
     42     /* A必须有一个右结点B */
     43     /* 将A与B做右单旋,更新A与B的高度,返回新的根结点B */ 
     44     AVLTree B = A->Right;
     45     A->Right = B->Left;
     46     B->Left = A;
     47     A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;
     48     B->Height = Max(GetHeight(B->Right), A->Height) + 1;
     49 
     50     return B; 
     51 }
     52 
     53 AVLTree DoubleLeftRightRotation(AVLTree A)
     54 {
     55     /* 注意:A必须有一个左子结点B,且B必须有一个右子结点C */
     56     /* 将A、B与C做两次单旋,返回新的根结点C */
     57     
     58     /* 将B与C做右单旋,C被返回 */
     59     A->Left = SingleRightRotation(A->Left);
     60     /* 将A与C做左单旋,C被返回 */
     61     return SingleLeftRotation(A);
     62 }
     63 
     64 AVLTree DoubleRightLeftRotation(AVLTree A)
     65 {
     66     A->Right = SingleLeftRotation(A->Right);
     67 
     68     return SingleRightRotation(A);    
     69 }
     70 
     71 AVLTree Insert(AVLTree T, ElementType X)
     72 {
     73     /* 将X插入AVL树T中,并且返回调整后的AVL树 */
     74     if(!T) {    /* 若插入空树,则新建包含一个结点的树 */
     75         T = (AVLTree)malloc(sizeof(struct AVLNode));
     76         T->Data = X;
     77         T->Height = 0;
     78         T->Left = T->Right = NULL;
     79     } else if(X < T->Data) {
     80         /* 插入T的左子树 */
     81         T->Left = Insert(T->Left, X);
     82         /* 如果需要左旋 */
     83         if(GetHeight(T->Left) - GetHeight(T->Right) == 2) {
     84             if(X < T->Left->Data)
     85                 T = SingleLeftRotation(T);      /* 左单旋 */
     86             else
     87                 T = DoubleLeftRightRotation(T); /* 左-右双旋 */
     88         }
     89     } else if(X > T->Data) {
     90         /* 插入T的右子树 */
     91         T->Right = Insert(T->Right, X);
     92         /* 如果需要右旋 */
     93         if(GetHeight(T->Left) - GetHeight(T->Right) == -2) {
     94             if(X > T->Right->Data)
     95                 T = SingleRightRotation(T);     /* 右单旋 */
     96             else
     97                 T = DoubleLeftRightRotation(T);    /* 左-右双旋 */
     98         }
     99     }
    100 
    101     /* 更新树高 */
    102     T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;
    103     return T;
    104 }


    无欲速,无见小利。欲速,则不达;见小利,则大事不成。
  • 相关阅读:
    Linux Shell常用shell命令
    shell ls
    [转]推荐一些不错的计算机书籍
    What does it mean when you assign [super init] to self?
    保存,读取与多任务处理
    程序媛去过的地方
    读取pcap文件,过滤非tcp包,获取IP及tcp端口信息
    IM实现联系人及联系人分组的数据库设计
    【原创】校园网用户,1个账号2个笔记本上网,Ad hoc无线连网应用
    【openfire插件开发】群组聊天中的中介者模式
  • 原文地址:https://www.cnblogs.com/ch122633/p/8763534.html
Copyright © 2011-2022 走看看