平衡二叉排序樹


 

因為二叉樹本身就是個遞歸的概念,所以在構建平衡二叉樹的時候,應時刻記得遞歸這個概念。

同樣的序列,因為排序不同,可能會生成不同的二叉排序樹,查找效率性對就不一定了,如:1-9這些數字就可以生成下面兩種樹。

第二種就是一個極端的情況,如果要查找9,就需要進行比較8次,效率很低。由此就引出,平衡二叉樹的概念。

什么是平衡二叉樹?

希望對一個序列,進行查找,最好的就是將其構建成一個平衡二叉樹即AVL樹。

但是怎么構建平衡二叉排序樹?

 前提:必須是一棵樹。(類似於:只有先保證他是一個人,才難說他是一個什么樣的男人。嘻嘻,這個比喻不是那么准確啦)

下面有一個題目:

怎么將左圖構建成右圖的平衡二叉樹呢?

可見,左圖和右圖的不同就在於是否是平衡的。左圖中節點9的平衡因子是2,是個不平衡點。

構造平衡二叉樹:

如果在一棵平衡的二叉搜索樹中,插入一個新節點時,造成了不平衡。此時必須調整樹的結構,使之平衡化。

平衡旋轉有兩類:

--單旋轉(左旋和右旋)

--雙旋轉(左右旋和右左旋)

每插入一個新節點時,AVL樹中相關節點的平衡狀態會發生改變。因此,在插入一個新節點后,需要從插入位置沿着通向根的路徑回溯,檢查各節點的平衡因子。如果在某一節點發現此樹不平衡,停止回溯。

從發生不平衡的節點起,沿着剛才回溯的路徑取直接下兩層的節點。

(1)如果這三個節點處在一條直線上,則采用單旋轉進行平衡化。單旋轉可按方向分為左單旋轉和右單旋轉。

(2)如果這三個節點處在一條折線上,則采用雙旋轉進行平衡化。單旋轉可按方向分為先左后右旋轉和先右后左旋轉。

下面舉兩個簡單的例子,便於理解。

1:a[10]={3,2,1,4,5,6,7,10,9,8};對於這壓樣一個一維數組,構建二叉平衡樹。

此時構建過程已經完成。

例子2:

 

下面是代碼實現:

  1 /*平衡二叉樹的實現原理
  2   時間:2015-6-21
  3 ***/
  4 #define LH 1//左子樹高
  5 #define EH 1//左右子樹登高
  6 #define RH 1//右子樹
  7 
  8 typedef struct BITNode{
  9   int data;
 10   int bf;
 11   struct BITNode*lchild,*rchild;
 12 }BITNode,*BiTree;
 13 //右旋操作
 14 void R_Rotate(BiTree *p)
 15 {
 16      BiTree L;
 17      L=(*p)->lchild;
 18      (*p)->lchild=L->rchild;
 19      L->rchild=(*p);
 20      *p=L;
 21 }
 22 //左旋操作
 23 void L_Rotate(BiTree *p)
 24 {
 25      BiTree L;
 26      L=(*p)->rchild;
 27      (*p)->rchild=L->lchild;
 28      L->lchild=(*p);
 29      *p=L;
 30 }
 31 //左平衡
 32 void LeftBalance(BiTree *T)
 33 {
 34    BiTree L,lr;
 35    L=(*T)->lchild;
 36    switch(L-bf)
 37    {
 38       case LH;
 39         (*T)->bf=L-bf=EH;
 40          R_RETATE(T)
 41          break;
 42          case RH;
 43           lr=L->rchild;
 44           switch(Lr-bf)
 45          {
 46          case LH;
 47             (*T)->bf=RH;
 48               L->bf=EH;
 49               break;
 50          case EH;
 51              (*T)->bf=L-bf=EH;
 52               break;
 53          case RH;
 54               (*T)->bf=EH;
 55                L-bf=LH;
 56                break;
 57    }
 58    lR->bf=EH;
 59    L_Rotate(&(*T)->lchild);
 60    R_Rotate(T);
 61    }
 62 
 63 }  
 64 int InsertAVL(BITree *T,int n,int *taller)//taller用於判斷插入節點后,樹長高了沒有
 65 {
 66  if(!*T)
 67    {
 68        *T=(BiTree)malloc(sizeod(BITNode));
 69        (*T)->data=e;
 70        (*T)->lchild=(*T)->rchild=NULL;
 71        (*T)->bf=EH;
 72         *taller=TRUE;
 73    }
 74  else{
 75        if(e==(*T)->data)
 76        {
 77        *taller=FALSE;
 78        return FALSE;
 79        }
 80        if(e<(*T)->data)
 81        {
 82         if(!InsertAVL(&(*T))->lchild,e,taller)
 83         {
 84            return FALSE;
 85          }
 86          if(*taller)//判斷樹的長勢
 87          {
 88             switch((*T)->bf)
 89             {
 90               case LH:
 91                         LeftBalance(T);
 92                          *taller=FALSE;
 93                          break;
 94                case EH:
 95                            (*T)->bf=EH;
 96                            *taller=TRUE;
 97                            break;
 98                 case RH:
 99                           (*T)->bf=EH;
100                            *taller=FALSE;
101   
102             }  
103          }
104  
105         }
106         else
107         {
108           if(!InsertAVL(&(*T))->rchild,e,taller)
109           {
110            return FALSE;
111            }
112            if(*taller)//判斷樹的長勢
113            {
114             switch((*T)->bf)
115             {
116               case LH:
117                         (*T)->bf=EH;
118                          *taller=FALSE;
119                          break;
120                case EH:
121                            (*T)->bf=EH;
122                            *taller=TRUE;
123                            break;
124                 case RH:
125                            RightBalance(T);
126                           (*T)->bf=EH;
127                            *taller=FALSE;
128   
129             }  
130          }
131  
132         }
133     }    
134 }

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM