平衡二叉樹

平衡二叉樹又稱AVL樹。它或者是顆空樹,或者是具有下列性質的二叉樹:它的左子樹和右子樹都是平衡二叉樹,且左子樹和右子樹的深度之差的絕對值不超過1。若將二叉樹節點的平衡因子BF定義爲該節點的左子樹的深度減去它的右子樹的深度,則平衡二叉樹上所有節點的平衡因子只可能爲-1,0,1.只要二叉樹上有一個節點的平衡因子的絕對值大於1,那麼這顆平衡二叉樹就失去了平衡。

假設我們已經有棵平衡二叉樹,現在讓我們來看看插入節點後,原來節點失去平衡後,我們進行選擇的處理方式。



平衡二叉樹多用於查找數據,所以平衡二叉樹又是顆二叉排序樹。

那麼如何創建一顆平衡二叉樹呢?

創建平衡二叉樹,我們採用依次插入節點的方式進行。而平衡二叉樹上插入節點採用遞歸的方式進行。遞歸算法如下:

(1)      若該樹爲一空樹,那麼插入一個數據元素爲e的新節點作爲平衡二叉樹的根節點,樹的高度增加1。

(2)      若待插入的數據元素e和平衡二叉樹(BBST)的根節點的關鍵字相等,那麼就不需要進行插入操作。

(3)      若待插入的元素e比平衡二叉樹(BBST)的根節點的關鍵字小,而且在BBST的左子樹中也不存在和e有相同關鍵字的節點,則將e插入在BBST的左子樹上,並且當插入之後的左子樹深度增加1時,分別就下列情況處理之。

(a)    BBST的根節點的平衡因子爲-1(右子樹的深度大於左子樹的深度):則將根節點的平衡因子更改爲0,BBST的深度不變;

(b)    BBST的根節點的平衡因子爲0(左右子樹的深度相等):則將根節點的平衡因子修改爲1,BBST的深度增加1;

(c)    BBST的根節點的平衡因子爲1(左子樹的深度大於右子樹的深度):若BBST的左子樹根節點的平衡因子爲1,則需要進行單向右旋轉平衡處理,並且在右旋處理後,將根節點和其右子樹根節點的平衡因子更改爲0,樹的深度不變;

若BBST的左子樹根節點的平衡因子爲-1,則需進行先向左,後向右的雙向旋轉平衡處理,並且在旋轉處理之後,修改根節點和其左,右子樹根節點的平衡因子,樹的深度不變;

(4)      若e的關鍵字大於BBST的根節點的關鍵字,而且在BBST的右子樹中不存在和e有相同關鍵字的節點,則將e插入到BBST的右子樹上,並且當插入之後的右子樹深度加1時,分別就不同的情況處理之。

(a)      BBST的根節點的平衡因子是1(左子樹的深度大於右子樹的深度):則將根節點的平衡因子修改爲0,BBST的深度不變;

(b)      BBST的根節點的平衡因子是0(左右子樹的深度相等):則將根節點的平衡因子修改爲-1,樹的深度加1;

(c)      BBST的根節點的平衡因子爲-1(右子樹的深度大於左子樹的深度):若BBST的右子樹根節點的平衡因子爲1,則需要進行兩次選擇,第一次先向右旋轉,再向左旋轉處理,並且在旋轉處理之後,修改根節點和其左,右子樹根節點的平衡因子,樹的深度不變;

若BBST的右子樹根節點的平衡因子爲1,則需要進行一次向左的旋轉處理,並且在左旋之後,更新根節點和其左,右子樹根節點的平衡因子,樹的深度不變;


下面附上本人的代碼:

  1. #include <stdio.h>  
  2. #include <stdlib.h>  
  3. /************************************************************************/  
  4. /*                    平衡二叉樹---AVL                                  */  
  5. /************************************************************************/  
  6. #define LH +1  
  7. #define EH  0  
  8. #define RH -1  
  9. typedef int ElemType;  
  10. typedef struct BSTNode{  
  11.     ElemType data;  
  12.     int bf;//balance flag  
  13.     struct BSTNode *lchild,*rchild;  
  14. }*PBSTree;  
  15.   
  16. void R_Rotate(PBSTree* p)  
  17. {  
  18.     PBSTree lc = (*p)->lchild;  
  19.     (*p)->lchild = lc->rchild;  
  20.     lc->rchild = *p;  
  21.     *p = lc;  
  22. }  
  23.   
  24. void L_Rotate(PBSTree* p)  
  25. {  
  26.     PBSTree rc = (*p)->rchild;  
  27.     (*p)->rchild = rc->lchild;  
  28.     rc->lchild = *p;  
  29.     *p = rc;  
  30. }  
  31.   
  32. void LeftBalance(PBSTree* T)  
  33. {  
  34.     PBSTree lc,rd;  
  35.     lc = (*T)->lchild;  
  36.     switch (lc->bf)  
  37.     {  
  38.     case LH:  
  39.         (*T)->bf = lc->bf = EH;  
  40.         R_Rotate(T);  
  41.         break;  
  42.     case RH:  
  43.         rd = lc->rchild;  
  44.         switch(rd->bf)  
  45.         {  
  46.         case LH:  
  47.             (*T)->bf = RH;  
  48.             lc->bf = EH;  
  49.             break;  
  50.         case EH:  
  51.             (*T)->bf = lc->bf = EH;  
  52.             break;  
  53.         case RH:  
  54.             (*T)->bf = EH;  
  55.             lc->bf = LH;  
  56.             break;  
  57.         }  
  58.         rd->bf = EH;  
  59.         L_Rotate(&(*T)->lchild);  
  60.         R_Rotate(T);  
  61.         break;  
  62.     }  
  63. }  
  64.   
  65. void RightBalance(PBSTree* T)  
  66. {  
  67.     PBSTree lc,rd;  
  68.     lc= (*T)->rchild;  
  69.     switch (lc->bf)  
  70.     {  
  71.     case RH:  
  72.         (*T)->bf = lc->bf = EH;  
  73.         L_Rotate(T);  
  74.         break;  
  75.     case LH:  
  76.         rd = lc->lchild;  
  77.         switch(rd->bf)  
  78.         {  
  79.         case LH:  
  80.             (*T)->bf = EH;  
  81.             lc->bf = RH;  
  82.             break;  
  83.         case EH:  
  84.             (*T)->bf = lc->bf = EH;  
  85.             break;  
  86.         case RH:  
  87.             (*T)->bf = EH;  
  88.             lc->bf = LH;  
  89.             break;  
  90.         }  
  91.         rd->bf = EH;  
  92.         R_Rotate(&(*T)->rchild);  
  93.         L_Rotate(T);  
  94.         break;  
  95.     }  
  96. }  
  97.   
  98. int InsertAVL(PBSTree* T,ElemType e,bool* taller)  
  99. {  
  100.     if ((*T)==NULL)  
  101.     {  
  102.         (*T)=(PBSTree)malloc(sizeof(BSTNode));  
  103.         (*T)->bf = EH;  
  104.         (*T)->data = e;  
  105.         (*T)->lchild = NULL;  
  106.         (*T)->rchild = NULL;  
  107.     }  
  108.     else if (e == (*T)->data)  
  109.     {  
  110.         *taller = false;  
  111.         return 0;  
  112.     }  
  113.     else if (e < (*T)->data)  
  114.     {  
  115.         if(!InsertAVL(&(*T)->lchild,e,taller))  
  116.             return 0;  
  117.         if(*taller)  
  118.         {  
  119.             switch ((*T)->bf)  
  120.             {  
  121.             case LH:  
  122.                 LeftBalance(T);  
  123.                 *taller = false;  
  124.                 break;  
  125.             case  EH:  
  126.                 (*T)->bf = LH;  
  127.                 *taller = true;  
  128.                 break;  
  129.             case RH:  
  130.                 (*T)->bf = EH;  
  131.                 *taller = false;  
  132.                 break;  
  133.             }  
  134.         }  
  135.     }  
  136.     else  
  137.     {  
  138.         if(!InsertAVL(&(*T)->rchild,e,taller))  
  139.             return 0;  
  140.         if (*taller)  
  141.         {  
  142.             switch ((*T)->bf)  
  143.             {  
  144.             case LH:  
  145.                 (*T)->bf = EH;  
  146.                 *taller = false;  
  147.                 break;  
  148.             case EH:  
  149.                 (*T)->bf = RH;  
  150.                 *taller = true;  
  151.                 break;  
  152.             case  RH:  
  153.                 RightBalance(T);  
  154.                 *taller = false;  
  155.                 break;  
  156.             }  
  157.         }  
  158.     }  
  159.     return 1;  
  160. }  
  161.   
  162. bool FindNode(PBSTree root,ElemType e,PBSTree* pos)  
  163. {  
  164.     PBSTree pt = root;  
  165.     (*pos) = NULL;  
  166.     while(pt)  
  167.     {  
  168.         if (pt->data == e)  
  169.         {  
  170.             //找到節點,pos指向該節點並返回true  
  171.             (*pos) = pt;  
  172.             return true;  
  173.         }  
  174.         else if (pt->data>e)  
  175.         {  
  176.             pt = pt->lchild;  
  177.         }  
  178.         else  
  179.             pt = pt->rchild;  
  180.     }  
  181.     return false;  
  182. }  
  183. void InorderTra(PBSTree root)  
  184. {  
  185.     if(root->lchild)  
  186.         InorderTra(root->lchild);  
  187.     printf("%d ",root->data);  
  188.     if(root->rchild)  
  189.         InorderTra(root->rchild);  
  190. }  
  191.   
  192. int main()  
  193. {  
  194.     int i,nArr[] = {1,23,45,34,98,9,4,35,23};  
  195.     PBSTree root=NULL,pos;  
  196.     bool taller;  
  197.     for (i=0;i<9;i++)  
  198.     {  
  199.         InsertAVL(&root,nArr[i],&taller);  
  200.     }  
  201.     InorderTra(root);  
  202.     if(FindNode(root,103,&pos))  
  203.         printf("\n%d\n",pos->data);  
  204.     else  
  205.         printf("\nNot find this Node\n");  
  206.     return 0;  
  207. }  

發佈了82 篇原創文章 · 獲贊 100 · 訪問量 63萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章