平衡二叉树

来源:互联网 发布:网络免费打电话下载 编辑:程序博客网 时间:2024/04/29 20:42

前面已经讲过平衡二叉树的实现原理以及实例

原理参见 http://blog.csdn.net/wxbmelisky/article/details/47755753     

实例参见 http://blog.csdn.net/wxbmelisky/article/details/47787963

平衡二叉树的实现代码如下

[cpp] view plain copy
 print?
  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3.   
  4. #define TRUE  1  
  5. #define FALSE 0  
  6.   
  7. // 定义平衡二叉树的结点结构  
  8. typedef struct BiTNode  
  9. {  
  10.     int data;  
  11.     int bf;             // 平衡因子  
  12.     BiTNode *lchild, *rchild;  
  13. }BiTNode, *BiTree;  
  14.   
  15. typedef int Status;  
  16.   
  17. // 右旋处理,即LL调整  
  18. void R_Rotate( BiTree *p )  
  19. {  
  20.     BiTree L;  
  21.     L = (*p)->lchild;  
  22.     (*p)->lchild = L->rchild;  
  23.     L->rchild = *p;  
  24.     *p = L;  
  25. }  
  26.   
  27. // 左旋处理,即RR调整  
  28. void L_Rotate( BiTree *p )  
  29. {  
  30.     BiTree R;  
  31.     R = (*p)->rchild;  
  32.     (*p)->rchild = R->lchild;  
  33.     R->lchild = *p;  
  34.     *p = R;  
  35. }  
  36.   
  37. // 左平衡旋转处理,包括 LL 和 LR 调整  
  38. void LeftBalance( BiTree *T )  
  39. {  
  40.     BiTree L, Lr;  
  41.     L = (*T)->lchild;  
  42.     switch( L->bf )  
  43.     {  
  44.     case 1:        // 新结点插入在T的左孩子的左子树上,为LL型,作右旋处理即LL调整  
  45.         (*T)->bf = L->bf = 0;  
  46.         R_Rotate( T );  
  47.         break;  
  48.     case -1:        // 新结点插入在T的左孩子的右子树上,为LR型,作双旋处理  
  49.         Lr = L->rchild;  
  50.         switch( Lr->bf )  
  51.         {  
  52.         case 1:  
  53.             (*T)->bf = -1;  
  54.             L->bf = 0;  
  55.             break;  
  56.         case 0:  
  57.             (*T)->bf = L->bf = 0;  
  58.             break;  
  59.         case -1:  
  60.             (*T)->bf = 0;  
  61.             L->bf = 1;  
  62.             break;  
  63.         }  
  64.         Lr->bf = 0;  
  65.         L_Rotate( &(*T)->lchild );      // 先对T的左子树进行左旋处理即RR调整  
  66.         R_Rotate( T );                  // 再对T进行右旋处理即LL调整  
  67.     }  
  68. }  
  69.   
  70. // 右平衡旋转处理,包括 RR 和 RL 调整  
  71. void RightBalance( BiTree *T )  
  72. {  
  73.     BiTree R, Rl;  
  74.     R = (*T)->rchild;  
  75.     switch( R->bf )  
  76.     {  
  77.     case -1:        // 新结点插入在T的右孩子的右子树上,为RR型,作左旋处理即RR调整  
  78.         (*T)->bf = R->bf = 0;  
  79.         L_Rotate( T );  
  80.         break;  
  81.     case 1:        // 新结点插入在T的右孩子的左子树上,为RL型,作双旋处理  
  82.         Rl = R->lchild;  
  83.         switch( Rl->bf )  
  84.         {  
  85.         case 1:  
  86.             (*T)->bf = 0;  
  87.             R->bf = -1;  
  88.             break;  
  89.         case 0:  
  90.             (*T)->bf = R->bf = 0;  
  91.             break;  
  92.         case -1:  
  93.             (*T)->bf = 1;  
  94.             R->bf = 0;  
  95.             break;  
  96.         }  
  97.         Rl->bf = 0;  
  98.         R_Rotate( &(*T)->rchild );      // 先对T的左子树进行左旋即RR调整  
  99.         L_Rotate( T );                  // 再对T进行右旋即LL调整  
  100.     }  
  101. }  
  102.   
  103. // 若在平衡二叉树T中不存在和 e 具有相同数据的结点,则插入数据元素为 e 的新结点,  
  104. // 若因插入使二叉排序树失去平衡,则要作平衡调整,  
  105. // 布尔变量taller表示 T 的深度是否增加,TRUE表示增加,FALSE表示没有增加  
  106.   
  107. Status InsertAVL( BiTree *T, int e, Status *taller )  
  108. {  
  109.     if( !*T )  
  110.     {  
  111.         *T = (BiTree)malloc(sizeof(BiTNode));  
  112.         (*T)->data = e;  
  113.         (*T)->lchild = (*T)->rchild = NULL;  
  114.         (*T)->bf = 0;  
  115.         *taller = TRUE;  
  116.     }  
  117.     else  
  118.     {  
  119.         // 树中已有和e具有相同数据的结点,则不再插入  
  120.         if( e == (*T)->data )  
  121.         {  
  122.             *taller = FALSE;  
  123.             return FALSE;  
  124.         }  
  125.   
  126.         if( e < (*T)->data )    // 继续在T的左子树进行搜索  
  127.         {  
  128.             if( !InsertAVL( &(*T)->lchild, e, taller ) ) // InsertAVL( &(*T)->lchild, e, taller )得到的是T的左孩子结点(*T)->lchild的 data,bf 等相关信息  
  129.             {  
  130.                 return FALSE;  
  131.             }  
  132.   
  133.             // 如果e已插入到T的左子树中,且左子树深度增加  
  134.             if( *taller )  
  135.             {  
  136.                 switch( (*T)->bf )      // 检查T的平衡因子  
  137.                 {  
  138.                 case 1:                // 原本左子树比右子树高,再加上此结点,导致不平衡,需要作LL或LR调整  
  139.                     LeftBalance( T );  
  140.                     *taller = FALSE;  
  141.                     break;  
  142.                 case 0:                // 原本左右子树等高,再加上此结点,左子树增高  
  143.                     (*T)->bf = 1;  
  144.                     *taller = TRUE;  
  145.                     break;  
  146.                 case -1:                // 原本右子树比左子树高,再加上此结点,左右子树变为等高  
  147.                     (*T)->bf = 0;  
  148.                     *taller = FALSE;  
  149.                     break;  
  150.                 }  
  151.             }  
  152.         }  
  153.         else        // 在T的右子树进行搜索  
  154.         {  
  155.             if( !InsertAVL( &(*T)->rchlid, e, taller ) )  
  156.             {  
  157.                 return FALSE;  
  158.             }  
  159.   
  160.             if( *taller )  
  161.             {  
  162.                 switch( (*T)->bf )  
  163.                 {  
  164.                 case 1:                // 原先左子树比右子树高,现在左右子树等高  
  165.                     (*T)->bf = 0;  
  166.                     *taller = FALSE;  
  167.                     break;  
  168.                 case 0:                // 原先左右子树等高,现在右子树增高  
  169.                     (*T)->bf = -1;  
  170.                     *taller = TRUE;  
  171.                     break;  
  172.                 case -1:                // 原先右子树比左子树高,现在再加上此结点,导致不平衡,需要作 RR 或 RL 调整  
  173.                     RightBalance( T );  
  174.                     *taller = FALSE;  
  175.                     break;  
  176.                 }  
  177.             }  
  178.         }  
  179.     }  
  180.   
  181.     return TRUE;  
  182. }  
  183.   
  184. // 对于实例,我们可以这样创建平衡二叉树  
  185. void CreateAVL()  
  186. {  
  187.     int i;  
  188.     int a[10] = {2,1,0,3,4,5,6,9,8,7};  
  189.     BiTree T = NULL;  
  190.     Status taller;  
  191.   
  192.     for( i=0; i<10; i++ )  
  193.     {  
  194.         InsertAVL( &T, a[i], &taller );  
  195.     }  
  196. }  
原创粉丝点击