鱼C论坛

 找回密码
 立即注册
查看: 4593|回复: 12

[技术交流] 平衡二叉树【注释无敌版】

[复制链接]
发表于 2014-12-15 19:15:35 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. #include<stdio.h>
  2. #include<stdlib.h>
  3. #define EH 0                        /*等高*/
  4. #define LH 1                        /*左高*/
  5. #define RH -1                        /*右高*/
  6.        
  7. typedef int ElemType;                         /*数据类型*/

  8. typedef struct BiTree{
  9.         ElemType data;                                        /*数据元素*/
  10.         int BF;                                                 /*平衡因子*/
  11.         struct BiTree *lchild,*rchild;         /*左右子女指针*/
  12. }*Bitree,BitreeNode;


  13. int InsertAVL(Bitree *T,ElemType e,bool *taller);
  14. void LeftBalance(Bitree *T);
  15. void RightBalance(Bitree *T);
  16. void R_Rotate(Bitree *T);
  17. void L_Rotate(Bitree *T);
  18. bool *taller=(bool*)malloc(sizeof(bool));

  19. int main(void)
  20. {
  21.         int data;
  22.         Bitree T=NULL;
  23.         while(1)
  24.         {
  25.                 printf("enter the number(zero to exit):");
  26.                 scanf("%d",&data);
  27.                 if(0==data)break;
  28.                 InsertAVL(&T,data,taller);
  29.                
  30.         }
  31.        
  32.        
  33.        
  34.         return 0;
  35. }


  36. /*若在平衡的二叉排序树T 中不存在和e 有相同关键码的结点,则插入一个数据元素为e 的*/
  37. /*新结点,并反回1,否则反回0。若因插入而使二叉排序树失去平衡,则作平衡旋转处理,*/               
  38. /*布尔型变量taller 反映T 长高与否*/       
  39. int InsertAVL(Bitree *T,ElemType e,bool *taller)
  40. {
  41.         if(!*T)                                /*插入新结点,树“长高”,置taller 为TURE*/
  42.         {
  43.                 (*T)=(Bitree)malloc(sizeof(BitreeNode));
  44.                 (*T)->data = e;
  45.                 (*T)->lchild = (*T)->rchild = NULL;
  46.                 (*T)->BF = EH;
  47.                 *taller = true;
  48.         }
  49.         else
  50.         {
  51.                 if(e==(*T)->data)                /*树中存在和e 有相同关键码的结点,不插入*/
  52.                 {
  53.                         *taller = false;
  54.                         return 0;
  55.                 }       
  56.                 if(e<(*T)->data)
  57.                 {
  58.                         if(!InsertAVL(&(*T)->lchild,e,taller))        return 0;  /*未插入*/
  59.                         if(*taller)
  60.                         switch((*T)->BF)
  61.                         {       
  62.                                 case EH :                                        /*原本左、右子树等高,因左子树增高使树增高*/
  63.                                         (*T)->BF=LH;
  64.                                         *taller=true;
  65.                                         break;
  66.                                
  67.                                 case LH :                                        /*原本左子树高,需作左平衡处理*/
  68.                                         LeftBalance(T);
  69.                                         *taller=false;
  70.                                         break;
  71.                                
  72.                                 case RH :                                        /*原本右子树高,使左、右子树等高*/
  73.                                         (*T)->BF=EH;
  74.                                         *taller=false;
  75.                                         break;
  76.                                        
  77.                         }
  78.                        
  79.                 }
  80.                 else
  81.                 {
  82.                         if(!InsertAVL(&(*T)->rchild,e,taller))        return 0;  /*未插入*/
  83.                         if(*taller)
  84.                         switch((*T)->BF)
  85.                         {       
  86.                                 case EH :                                        /*原本左、右子树等高,因右子树增高使树增高*/
  87.                                         (*T)->BF=RH;
  88.                                         *taller=true;
  89.                                         break;
  90.                                
  91.                                 case LH :                                        /*原本左子树高,使左、右子树等高*/
  92.                                         (*T)->BF=EH;
  93.                                          *taller=false;
  94.                                          break;
  95.                                
  96.                                 case RH :                                        /*原本右子树高,需作右平衡处理*/
  97.                                         RightBalance(T);
  98.                                         *taller=false;
  99.                                          break;
  100.                                        
  101.                         }
  102.                 }
  103.         }
  104.         return 1;
  105. }



  106. /*对以*p 指向的结点为根的子树,作左平衡旋转处理,处理之后,*p 指向的结点为子树的新根*/
  107. void LeftBalance(Bitree *T)
  108. {
  109.         Bitree L=(*T)->lchild,Lr;                         /*L 指向*T左子树根结点*/
  110.         switch(L->BF)                                /*检查L 平衡度,并作相应处理*/
  111.         {
  112.                 case LH:                                        /*新结点插在*p 左子树的左子树上,需作单右旋转处理*/
  113.                         (*T)->BF=L->BF=EH;
  114.                          R_Rotate(T);
  115.                          break;
  116.                 case EH:                         /*原本左、右子树等高,因左子树增高使树增高*/
  117.                         (*T)->BF=LH;    //这里的EH好像没有写的必要
  118.                           *taller=true;
  119.                           break;
  120.                 case RH:                                         /*新结点插在*T 左孩子的右子树上,需作先左后右双旋处理*/
  121.                         Lr=L->rchild;                         /*Lr 指向*p 左孩子的右子树根结点*/       
  122.                         switch(Lr->BF)         /*修正*T 及其左子树的平衡因子*/
  123.                         {
  124.                                 case LH:
  125.                                         (*T)->BF = RH;
  126.                                         L->BF = EH;
  127.                                         break;
  128.                                 case EH:
  129.                                         (*T)->BF = L->BF= EH;
  130.                                         break;
  131.                                 case RH:
  132.                                         (*T)->BF = EH;
  133.                                         L->BF = LH;
  134.                                         break;
  135.                                
  136.                         }
  137.                         Lr->BF = EH;
  138.                         L_Rotate(&L);                /*对*T 的左子树作左旋转处理*/
  139.                         R_Rotate(T);                /*对*T 作右旋转处理*/
  140.         }
  141. }
  142. //这里和leftbalance一个道理,试着自己写一下
  143. void RightBalance(Bitree *T)
  144. {
  145.         Bitree Lr= (*T)->rchild,L;
  146.         switch(Lr->BF)
  147.         {
  148.                 case EH:
  149.                         *taller = true;
  150.                         (*T)->BF = RH;
  151.                         break;
  152.                 case RH:
  153.                         (*T)->BF=Lr->BF=EH;
  154.                         L_Rotate(T);
  155.                         break;
  156.                 case LH:
  157.                         L = Lr->lchild;
  158.                         switch(L->BF)
  159.                         {
  160.                                 case EH:
  161.                                         (*T)->BF=Lr->BF= EH;
  162.                                         break;
  163.                                 case RH:
  164.                                         Lr->BF= EH;
  165.                                         (*T)->BF = LH;
  166.                                         break;
  167.                                 case LH:
  168.                                         (*T)->BF = LH;
  169.                                         Lr->BF = EH;
  170.                                         break;
  171.                                
  172.                         }
  173.                         L->BF = EH;
  174.                         R_Rotate(&Lr);               
  175.                         L_Rotate(T);       
  176.                
  177.         }
  178. }


  179. /*对以*T 指向的结点为根的子树,作右单旋转处理,处理之后,*T 指向的结点为子树的新根*/
  180. void R_Rotate(Bitree *T)
  181. {
  182.         Bitree L=(*T)->lchild;                                 /*L 指向*T 左子树根结点*/
  183.         (*T)->lchild=L->rchild;                                 /*L 的右子树挂接*T 的左子树*/
  184.         L->rchild=*T; *T=L;                         /* *L 指向新的根结点*/
  185. }


  186. /*对以*p 指向的结点为根的子树,作左单旋转处理,处理之后,*p 指向的结点为子树的新根*/
  187. void L_Rotate(Bitree *T)
  188. {
  189.         Bitree Lr=(*T)->rchild;                                 /*Lr 指向*T 右子树根结点*/
  190.         (*T)->rchild=Lr->lchild;                                 /*L 的左子树挂接*p 的右子树*/
  191.         Lr->lchild=*T;
  192.         *T=Lr;                                                                         /* *L 指向新的根结点*/
  193. }
复制代码


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-12-15 19:16:52 | 显示全部楼层
,,理解了一下午,,,
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2014-12-15 22:14:18 | 显示全部楼层
好难啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-1-14 20:08:47 | 显示全部楼层
不错,谢谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-1-21 10:01:35 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-22 19:46:23 | 显示全部楼层
谢谢分享!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-23 12:47:28 | 显示全部楼层
谢谢分享
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 01:39:41 | 显示全部楼层
感谢额 我看看学习学习
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-26 21:42:50 | 显示全部楼层
看看。。。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2015-5-26 22:11:25 | 显示全部楼层
LZ好人。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-27 02:59:17 | 显示全部楼层

LZ好人。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2015-5-27 22:23:33 | 显示全部楼层


LZ好人。。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2016-12-23 13:58:21 | 显示全部楼层
感谢 楼主 奉献
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 15:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表