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

      1 #include<time.h>
      2 #include<stdio.h>  
      3 #include<stdlib.h> 
      4 //左子树比右子树高一
      5 #define LH 1
      6 //左子树和右子树一样高
      7 #define EH 0
      8 //左子树比右子树低一
      9 #define RH -1
     10 #define EQ(a,b) ((a) == (b))
     11 #define LT(a,b) ((a) < (b))
     12 #define LQ(a,b)((a) <= (b))
     13 
     14 typedef struct BSTNode
     15 {
     16     int data;
     17     int bf;
     18     BSTNode * lchild;
     19     BSTNode * rchild;
     20 }BSTNode;
     21 typedef BSTNode * BSTree;
     22 
     23 //    左旋
     24 void leftRotate(BSTree & root) 
     25 {
     26     BSTree rc = root->rchild;
     27     root->rchild = rc->lchild;
     28     rc->lchild = root;
     29     root = rc;
     30 }
     31 //    右旋
     32 void rightRotate(BSTree & root) 
     33 {
     34     BSTree lc = root->lchild;
     35     root->lchild = lc->rchild;
     36     lc->rchild = root;
     37     root = lc;
     38 }
     39 //    对二叉树root进行左平衡处理(LL型和LR型)
     40 void leftBalance(BSTree & root) 
     41 {
     42     BSTree lc = root->lchild;
     43     switch (lc->bf) 
     44     {
     45         //LL型的只需要进行右旋操作
     46     case LH:
     47         //右旋之后根和左子树都的平衡的
     48         root->bf = EH;
     49         lc->bf = EH;
     50         //右旋操作
     51         rightRotate(root);
     52         break;
     53         //LR型的需要进行左旋操作,然后右旋操作
     54     case RH:
     55         BSTree rc = lc->rchild;
     56         switch (rc->bf) 
     57         {
     58         case LH:
     59             root->bf = RH;
     60             lc->bf = EH;
     61             break;
     62         case EH:
     63             root->bf = EH;
     64             lc->bf = EH;
     65             break;
     66         case RH:
     67             root->bf = EH;
     68             lc->bf = LH;
     69             break;
     70         }
     71         rc->bf = EH;
     72         leftRotate(root->lchild);
     73         rightRotate(root);
     74         break;
     75     }
     76 }
     77 //    功能:对二叉树root进行左平衡处理(RR型和RL型)
     78 void rightBalance(BSTree & root) 
     79 {
     80     BSTree rc = root->rchild;
     81     switch (rc->bf) 
     82     {
     83         //RR型只需要做左旋操作
     84     case RH:
     85         root->bf = EH;
     86         rc->bf = EH;
     87         //左旋操作
     88         leftRotate(root);
     89         break;
     90         //RL型需要先做右旋操作,然后做左旋操作
     91     case LH:
     92         BSTree lc = rc->lchild;
     93         switch (lc->bf) 
     94         {
     95         case LH:
     96             root->bf = EH;
     97             rc->bf = RH;
     98             break;
     99         case EH:
    100             root->bf = EH;
    101             rc->bf = EH;
    102             break;
    103         case RH:
    104             root->bf = LH;
    105             rc->bf = EH;
    106             break;
    107         }
    108         lc->bf = EH;
    109         rightRotate(root->rchild);
    110         leftRotate(root);
    111         break;
    112     }
    113 }
    114 //    功能:把元素data插入平衡二叉树root中
    115 bool insert(BSTree & root, int data, bool & taller) 
    116 {
    117     if (NULL == root) 
    118     {
    119         root = (BSTree)malloc(sizeof(BSTNode));
    120         root->rchild = NULL;
    121         root->lchild = NULL;
    122         root->data = data;
    123         root->bf = EH;
    124         taller = true;
    125     }
    126     else
    127     {
    128         //该元素已经在平衡二叉树中存在了
    129         if (data == root->data) 
    130         {
    131             taller = false;
    132             return false;
    133         }
    134         //插入左子树
    135         else if (data < root->data) 
    136         {
    137             if (!insert(root->lchild, data, taller)) 
    138             {
    139                 return false;
    140             }
    141             //插入成功,并且树变高了
    142             if (taller) 
    143             {
    144                 switch (root->bf) 
    145                 {
    146                 case LH:
    147                     leftBalance(root);
    148                     //平衡二叉树做完左平衡操作后
    149                     //树高没有变化,故taller = false
    150                     taller = false;
    151                     break;
    152                 case EH:
    153                     root->bf = LH;
    154                     //原来是平衡的故插入一个元素后
    155                     //树高必然变高
    156                     taller = true;
    157                     break;
    158                 case RH:
    159                     root->bf = EH;
    160                     //原来是右子树比左子树高,但是当向左子树中
    161                     //插入一个元素的时候,树变平衡了,故taller = false
    162                     taller = false;
    163                     break;
    164                 default:
    165                     break;
    166                 }
    167             }
    168         }
    169         //插入右子树
    170         else 
    171         {
    172             if (!insert(root->rchild, data, taller)) 
    173             {
    174                 return 0;
    175             }
    176             if (taller) 
    177             {
    178                 switch (root->bf) 
    179                 {
    180                 case LH:
    181                     root->bf = EH;
    182                     taller = false;
    183                     break;
    184                 case EH:
    185                     root->bf = RH;
    186                     taller = true;
    187                     break;
    188                 case RH:
    189                     rightBalance(root);
    190                     taller = false;
    191                     break;
    192                 }
    193             }
    194         }
    195     }
    196     return true;
    197 }
    198 //   在平衡二叉树中查找int节点
    199 int * search(BSTree & root, int data) 
    200 {
    201     if (root ==NULL) 
    202     {
    203         return NULL;
    204     }
    205     
    206     if (root->data == data) 
    207     {
    208         return &root->data;
    209     }
    210     else if (data < root->data) 
    211     {
    212         return search(root->lchild, data);
    213     } 
    214     else 
    215     {
    216         return search(root->rchild, data);
    217     }
    218 }
    219 //    功能:输出平衡二叉树中的所有的元素(小->大,中序遍历)
    220 void print(BSTree & root)
    221 {
    222     if (NULL == root) 
    223     {
    224         return ;
    225     }
    226     
    227     print(root->lchild);
    228     printf("%d ",root->data);
    229     print(root->rchild);
    230 }
    231 //    功能:释放平衡二叉树的空间
    232 void clear(BSTree & root) 
    233 {
    234     if (NULL == root) 
    235     {
    236         return ;
    237     }
    238     clear(root->lchild);
    239     clear(root->rchild);
    240     free(root);
    241 }
    242 int DeleteAVL(BSTree &T, int key, bool &shorter){
    243     if (!T)
    244     {//No such key
    245         shorter = false;
    246         return 0;
    247     }
    248     else
    249     {
    250         if (EQ(key, T->data))    //找到了需要删除的结点
    251         {
    252             //如果该结点的lchild 和
    253             //rchild 至少有一个为NULL
    254             //则大功告成,否则请参照
    255             //下方解释
    256             BSTree q = T;
    257             if (!T->lchild)//如果该结点的lchild 为NULL
    258             {
    259                 q = T;
    260                 T = T->rchild;
    261                 free(q);
    262                 shorter = true;
    263                 return 1;
    264             }
    265             else if (!T->rchild){//如果该结点的rchild 为 NULL
    266                 q = T;
    267                 T = T->lchild;//如果不是&(引用)的强大功能,这句话是没有意义的
    268                 free(q);
    269                 shorter = true;
    270                 return 1;
    271             }
    272             else {
    273                 //删除一个左右孩子都不为空的结点
    274                 //使该结点的直接前驱p的data替换该结点的data
    275                 //然后改变key=p.data
    276                 BSTree s = T->lchild;
    277                 while (s->rchild)
    278                     s = s->rchild;
    279                 T->data = s->data;
    280                 key = s->data;//Now, delete the vertice whose data was the new key
    281             }
    282         }
    283         if (LQ(key, T->data)){//这里与InsertAVL不同
    284             if (!DeleteAVL(T->lchild, key, shorter)) return 0;
    285             if (shorter){
    286                 switch(T->bf){
    287                 case LH:T->bf = EH; shorter = true;break;
    288                 case EH:T->bf = RH;shorter = false;break;
    289                 case RH:rightBalance(T); 
    290                     if (T->rchild->bf == EH)
    291                         shorter = false;
    292                     else 
    293                         shorter = true;break;
    294                 }
    295             }
    296         }
    297         else{
    298             if (!DeleteAVL(T->rchild, key, shorter)) return 0;
    299             if (shorter){
    300                 switch(T->bf){
    301                 case LH:leftBalance(T);
    302                     if (T->lchild->bf == EH)
    303                         shorter = false;
    304                     else 
    305                         shorter = true;break;
    306                 case EH:T->bf = LH; shorter = false;break;
    307                 case RH:T->bf = EH;shorter = true;break;
    308                 }
    309             }
    310         }
    311     }
    312     return 1;
    313 }//Delete
    314 void menu()  
    315 {  
    316     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙    主菜单     ⊙☆⊙ ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  
    317     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 1:连续插入数据 输入0结束插入⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  
    318     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 2:查找数据                  ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  
    319     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 3删除特定数据               ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");  
    320     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 4输出当前结果                   ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n"); 
    321     printf("⊙☆⊙ ⊙☆⊙ ⊙☆⊙请按№ 5结束程序                   ⊙☆⊙ ⊙☆⊙ ⊙☆⊙\n");
    322 }  
    323 int main()
    324 {
    325     BSTree root = NULL;
    326     int num,n;
    327     bool taller = false,shorter;
    328     system("color 2e");  
    329     menu();
    330     while(1)  
    331     {  
    332         scanf("%d",&num); 
    333         //if(num==5) break;
    334         switch (num)  
    335         {  
    336         case 1:
    337             system("cls");
    338             printf("请插入数据 ,输入0结束插入\n");
    339             while(scanf("%d",&n))
    340             {
    341                 if(n==0) break;
    342                 else insert(root,n,taller);
    343             }
    344             system("cls");
    345             menu();
    346             break;
    347         case 2: 
    348             system("cls");
    349             printf("请输入要查询的数\n");
    350             scanf("%d",&n);
    351             int *p;
    352             p=search(root,n);
    353             if (p==NULL) 
    354             {
    355                 printf("对不起 没有找到 %d!\n",n);
    356             }
    357             else 
    358             {
    359                 printf("恭喜你 数据中存在 %d!\n",n);
    360             }
    361             menu();
    362             break;  
    363         case 3: 
    364             system("cls");
    365             printf("请输入要删除的数据\n");
    366             scanf("%d",&n);
    367             DeleteAVL(root,n,shorter);
    368             menu();
    369             break;
    370         case 4:
    371             system("cls");
    372             print(root); 
    373             printf("输入0进入主菜单\n");
    374             scanf("%d",&n);
    375             if(!n)
    376               menu();
    377             break;
    378         case 5:
    379             clear(root);
    380             return 0;        
    381         }
    382     }
    383     return 0;
    384 }

    原文转自:http://blog.csdn.net/hnust_xiehonghao/article/details/7938869

  • 相关阅读:
    python3.6中 字典类型和字符串类型互相转换的方法
    "sorted()"中的"Key Functions"
    tuple unpacking
    理解"__repr__"
    Python中的"Special Method"
    abstractmethod
    JavaScript括号中什么什么不加引号什么时候加引号?
    加载网页时速度慢的一些知识点
    Login登录页面的制作流程(摘要)
    JavaScript总结1
  • 原文地址:https://www.cnblogs.com/10jschen/p/2669935.html
Copyright © 2011-2022 走看看