zoukankan      html  css  js  c++  java
  • 数据结构【查找】—平衡二叉树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 }

      

  • 相关阅读:
    【SSH网上商城项目实战15】线程、定时器同步首页数据(类似于CSDN博客定期更新排名)
    【SSH网上商城项目实战14】商城首页UI的设计
    Spring工具类:WebApplicationContextUtils
    多线程技术: 两个线程交替打印奇数和偶数
    常见的几种异常类型Exception
    【SSH网上商城项目实战13】Struts2实现文件上传功能
    【SSH网上商城项目实战12】添加和更新商品功能的实现
    【SSH网上商城项目实战11】查询和删除商品功能的实现
    【SSH网上商城项目实战10】商品类基本模块的搭建
    如何防止通过IP地址访问Tomcat管理页面
  • 原文地址:https://www.cnblogs.com/zzw1024/p/10589445.html
Copyright © 2011-2022 走看看