• 数据结构【查找】—平衡二叉树AVL


    /*自己看了半天也没看懂代码,下次再补充说明*/

    解释:

      平衡二叉树(Self-Balancing Binary Search Tree 或Height-Balanced Binary Search Tree),是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。

    实现原理:

      平衡二叉树构建的基本思想就是在构建二又排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二又排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

    右旋:

      

    左旋:

      

    左旋、右旋:

      

    代码实现:

      

      1 #include "000库函数.h"
      2 
      3 #define MAXSIZE 100//
      4 #define EH 0
      5 #define LH +1  //左高
      6 #define RH -1  //右高  
      7 
      8 //二叉树的结构
      9 struct BiTree
     10 {
     11     int data;
     12     int bf;//AVL的平衡因子
     13     BiTree *lchild, *rchild;
     14 };
     15 
     16 bool L_Rotate(BiTree* &T) {//对T的左子树作左旋平衡处理
     17     BiTree *R;
     18     R = T->rchild;
     19     T->rchild = R->lchild;//R的左子树挂接为T的右子树
     20     R->lchild = T;
     21     T = R;
     22     return true;
     23 }
     24 
     25 bool R_Rotate(BiTree* &T) {//对T做右旋处理
     26     BiTree *L;
     27     L = T->lchild;
     28     T->lchild = L->rchild;
     29     L->rchild = T;
     30     T = L;
     31     return true;
     32 }
     33 
     34 
     35 
     36 
     37 //判断再加入左子树会不会打破平衡
     38 bool LeftBalace(BiTree* &T) {//如今再添加进左边就应该添加后判断是否打破了平衡
     39     BiTree *L, *Lr;
     40     L = T->lchild;
     41     switch (L->bf)//判断左子树的平衡因子
     42     {
     43     case LH://原为左增,现再增加就打破平衡了,故需要做右旋处理
     44         T->bf = L->bf = EH;
     45         R_Rotate(T);
     46         break;
     47     case RH://原节点为右增,再增加左节点(深度+1),就打破平衡了,故作双旋处理
     48         Lr = L->rchild;
     49         switch (Lr->bf)
     50         {
     51         case LH:
     52             T->bf = RH;
     53             L->bf = EH;
     54             break;
     55         case EH:
     56             T->bf = L->bf = EH;
     57             break;
     58         case RH:
     59             T->bf = EH;
     60             L->bf = LH;
     61             break;
     62         default:
     63             break;
     64         }
     65         Lr->bf = EH;
     66         L_Rotate(T->lchild);//对T的左子树作左旋平衡处理
     67         R_Rotate(T);//对T做右旋处理
     68         break;
     69     default:
     70         break;
     71     }
     72     return true;
     73 }
     74 
     75 //判断再加入右子树会不会打破平衡
     76 bool RightBalace(BiTree* &T) {//如今再添加进右边就应该添加后判断是否打破了平衡
     77     BiTree *R, *Rl;
     78     R = T->rchild;
     79     switch (R->bf)//判断右子树的平衡因子
     80     {
     81     case LH://原节点为左增,再增加右节点(深度+1),就打破平衡了,故作双旋处理        
     82         Rl = R->lchild;
     83         switch (Rl->bf)
     84         {
     85         case LH:
     86             T->bf = EH;
     87             R->bf = RH;
     88             break;
     89         case EH:
     90             T->bf = R->bf = EH;
     91             break;
     92         case RH:
     93             T->bf = LH;
     94             R->bf = EH;
     95             break;
     96         default:
     97             break;
     98         }
     99         Rl->bf = EH;
    100         R_Rotate(T->rchild);//对T的左子树作左旋平衡处理
    101         L_Rotate(T);//对T做右旋处理
    102         break;
    103     case RH://原为右增,现再增加就打破平衡了,故需要做左旋处理        
    104         T->bf = R->bf = EH;
    105         L_Rotate(T);
    106         break;         
    107     default:
    108         break;
    109     }
    110     return true;
    111 }
    112 
    113 //AVL创建
    114 /*  若在平衡的二叉排序树T中不存在和e有相同关键字的结点,则插入一个 */
    115 /*  数据元素为e的新结点,并返回1,否则返回0。若因插入而使二叉排序树 */
    116 /*  失去平衡,则作平衡旋转处理,布尔变量taller反映T长高与否。 */
    117 bool InsertAVL(BiTree * &T, int elem, bool &n) {
    118     if (T == NULL) {
    119         BiTree *p;
    120         p = new BiTree;
    121         p->data = elem;
    122         p->bf = EH;
    123         p->lchild = NULL;
    124         p->rchild = NULL;
    125         T = p;
    126         n = true;
    127         return true;
    128     }
    129     if (T->data == elem) {//数据已存在,不需要再添加
    130         n = false;
    131         return false;
    132     }
    133     if (elem < T->data) {
    134         if (!(InsertAVL(T->lchild, elem, n)))//应当继续在左子树中继续查找
    135             return false;//添加失败
    136         if (n) {//添加成功
    137             switch (T->bf)//检查AVL的平衡因子
    138             {
    139             case LH://原树左边高
    140                 LeftBalace(T);//如今再添加进左边就应该添加后判断是否打破了平衡
    141                 n = false;
    142                 break;
    143             case EH://原树左等高度,那就加入其左边,让其增高
    144                 T->bf = LH;
    145                 n = true;
    146                 break;
    147             case RH://原树右端高,那就加入左端,抵消有右边的高度
    148                 T->bf = EH;
    149                 n = false;
    150                 break;
    151             default:
    152                 break;
    153             }
    154         }            
    155     }
    156     else {
    157         if (!(InsertAVL(T->rchild, elem, n)))//应当继续在右子树中继续查找
    158             return false;//添加失败
    159         if (n) {//添加成功
    160             switch (T->bf)//检查AVL的平衡因子
    161             {
    162             case LH://原树左边高
    163                 T->bf = EH;//加入右端,抵消有左边的高度
    164                 n = false;
    165                 break;
    166             case EH://原树左等高度,那就加入其右边,让其增高
    167                 T->bf = LH;
    168                 n = true;
    169                 break;
    170             case RH://原树右端高
    171                 RightBalace(T);//如今再添加进右边就应该添加后判断是否打破了平衡
    172                 n = false;
    173                 break;
    174             default:
    175                 break;
    176             }
    177         }
    178     }
    179 
    180 
    181 }
    182 //遍历AVL
    183 void ShowTree(BiTree *T) {
    184     //进行中序浏览
    185     if (T) {
    186         ShowTree(T->lchild);
    187         cout << T->data << "—>";
    188         ShowTree(T->rchild);
    189     }
    190 }
    191 
    192 int T033(void)
    193 {
    194     int i;
    195     int a[10] = { 3,2,1,4,5,6,7,10,9,8 };
    196     BiTree *T = new BiTree;
    197     T = NULL;
    198     bool taller;//用来判断AVL是否增加了深度
    199     BiTree *p;
    200     for (i = 0; i < 10; i++)    {
    201         InsertAVL(T, a[i], taller);
    202         if (i == 0)p = T;//记住头结点
    203     }
    204     ShowTree(T);
    205     cout << endl;
    206     return 0;
    207 }

      

  • 相关阅读:
    重新想象 Windows 8 Store Apps (15) 控件 UI: 字体继承, Style, ControlTemplate, SystemResource, VisualState, VisualStateManager
    重新想象 Windows 8 Store Apps (12) 控件之 GridView 特性: 拖动项, 项尺寸可变, 分组显示
    返璞归真 asp.net mvc (10) asp.net mvc 4.0 新特性之 Web API
    与众不同 windows phone (29) Communication(通信)之与 OData 服务通信
    与众不同 windows phone (33) Communication(通信)之源特定组播 SSM(Source Specific Multicast)
    与众不同 windows phone (27) Feature(特性)之搜索的可扩展性, 程序的生命周期和页面的生命周期, 页面导航, 系统状态栏
    与众不同 windows phone (30) Communication(通信)之基于 Socket TCP 开发一个多人聊天室
    返璞归真 asp.net mvc (12) asp.net mvc 4.0 新特性之移动特性
    重新想象 Windows 8 Store Apps (2) 控件之按钮控件: Button, HyperlinkButton, RepeatButton, ToggleButton, RadioButton, CheckBox, ToggleSwitch
    重新想象 Windows 8 Store Apps (10) 控件之 ScrollViewer 特性: Chaining, Rail, Inertia, Snap, Zoom
  • 原文地址:https://www.cnblogs.com/zzw1024/p/10589445.html
Copyright © 2020-2023  润新知