平衡二叉樹的C語言實現(建立、插入、尋找、刪除、旋轉)【資料結構】

來源:互聯網
上載者:User

平衡二叉樹(AVL)或者是一顆空樹,或者是具有下列性質的非空二叉搜尋樹:

(1). 任一結點的左、右子樹均為AVL樹;

(2). 任一結點的左、右子樹高度差的絕對值不超過1。


對於二叉樹中任一結點T,其“平衡因子”(Balance Factor, BF)定義為BF(T) = Hl-Hr,其中Hl和Hr分別為T的左、右子樹的高度。


有了平衡因子的定義,AVL樹“任一結點左右子樹高度差的絕對值不超過1”這一性質可以表述為“一棵AVL樹中任一結點的平衡因子只能在集合{-1,0,1}中取值”。這就是平衡的量化標準。


當一棵AVL樹插入或刪除一個結點時,該結點的平衡因子很可能不在上述集合範圍內,破壞了樹的平衡,這時就需要做“平衡化”處理,即相應的局部“旋轉”調整,使得調整後的樹達到平衡。


(1). 單旋調整(左左、右右)


(2). 雙旋調整(左-右、右-左)



基本操作:

//=========================================================================================//                              平衡二叉樹---AVL//=========================================================================================//Define an AVLTreetypedef struct AVLTreeNode *AVLTree;typedef struct AVLTreeNode{    int Data;    AVLTree Left;    AVLTree Right;    int Height;}//=========================================================================================//平衡二叉樹的插入操作(按中序操作)AVLTree AVL_Insertion(ElementType X, AVLTree T){//將X插入樹T中,並返回調整後的樹    if(!T){        T = malloc(sizeof(AVLTreeNode));        T->Data = X;        T->Height = 0;        T->Left = T->Right = NULL;    }    else if(X < T->Data){        T->Left = AVL_Insertion(X, T->Left);    //遞迴比較並插入,將插入後的左子樹更新給T-Left        if(GetHeight(T->Left) - GetHeight(T->Right) == 2)            if(X < T->Left->Data)                T = SingleLeftRotation(T);  //左單旋            else                T = DoubleLeftRightRotation(T); //左-右雙旋    }    else if(X > T->Data){        T->Right = AVL_Insertion(X, T->Right);  //遞迴比較並插入,將插入後的右子樹更新給T->Right        if(GetHeight(T->Left) - GetHeight(T->Right) == -2)            if(X > T->Right->Data)                                            T = SingleLeftRotation(T);  //右單旋                           else                                                         T = DoubleRightLeftRotation(T); //右-左雙旋                }            //else X == T->Data, 無需插入    T->Height = Max(GetHeight(T->Left), GetHeight(T->Right)) + 1;//樹高等於子樹高度加一        return T;   //返回插入並調整後的樹}//=========================================================================================//左單旋演算法AVLTree SingleLeftRotation(AVLTree A){//注意:A必須有一個左子結點B//將A與B做左單旋,更新A與B的高度,返回新的根結點B    AVLTree B = A->Left;    A->Left = B->Right;    B->Right = A;    A->Height = Max(GetHeight(A->Left), GetHeight(A->Right)) + 1;    B->Height = Max(GetHeight(B->Left), GetHeight(A->Height)) + 1;    return B;}//=========================================================================================//左-右雙旋演算法AVLTree DoubleLeftRightRotation(AVLTree A){//注意:A必須有一個左子結點B,且B必須有一個右子結點C//將A.B與C做單旋兩次,返回新的根結點C    A->Left = SingleRightRotation(A->Left);//將B與C做右單旋,C被返回    return SingleLeftRotation(A);   //將A與C做左單旋,C被返回}//=========================================================================================//平衡二叉樹的尋找操作AVLTree Find(ElementType X, AVLTree T){    if(!T)        return NULL;    if(X < T->Data)        return Find(X, T->Left);    else if(X > T->Data)        return Find(X, T->Right);    else        return T;}//=========================================================================================//平衡二叉樹的刪除操作//刪除方法與二叉尋找樹一致,區別是,刪除完成後,需要從刪除節點的父親開始向上維護樹的//平衡一直到根結點(調整樹)。AVLTree Delete(ElementType X, AVLTree T){    if(!T){         //樹為空白,報錯        printf("ERROR!");        return NULL;    }    if(X < T->Data)        T->Left = Delete(X, T->Left);   //遞迴尋找並刪除指定元素X     else if(X > T->Data)        T->Right = Delete(X, T->Right);    else{        if(T->Left && T->Right){    //此結點含有左右兩個子樹                    AVLTree Tmp = T->Right;            while(Tmp->Left != NULL)    //尋找T的右子樹的最小值用於填補刪除的元素的位置                Tmp = Tmp->Left;            T->Data = Tmp->Data;            T->Right = Delete(Tmp->Data, T->Right);//刪除移位後的Tmp->Data            if(GetHeight(T->Left) - GetHeight(T->Right) == 2){                //將T看做根結點,刪除的元素在右子樹,此時判斷左子樹與右子樹的高度差是不是>=2                //若是,則判斷左子樹是左單旋還是左-右雙旋                //若T->Left的右子樹比左子樹長,則為左-右雙旋                //若T->Left的左子樹比右子樹長,則為左單旋                //              A                //             /            A為T, B為T->Left                //            B             若C分支長(T->Left->Left),則為左單旋                //           / \            若D分支長(T->Left->Right),則為左右雙旋                //          C   D                //          :   :                if((T->Left->Right != NULL) && GetHeight(T->Left->Right) > GetHeight(T->Left->Left))                    DoubleLeftRightRotation(T); //調用左-右雙旋演算法                else                    SingleLeftRotation(T);  //調用左單旋演算法            }        }else{  //此結點含有一個或零個子樹            AVLTree Tmp = T;            if(!T->Left)                T = T->Right;            else if(!T->Right)                T = T->Left;            free(Tmp);  //釋放Tmp        }    }    T->Height = Max(GetHeight(T->Left), GetHeight(T->Right));    return T;}


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.