天天看點

二叉排序平衡樹查找-動态查找

二叉排序平衡樹查找-動态查找

更新:2013-12-02

//

需要掌握的前提知識是二叉排序樹查找

名稱:二叉排序平衡樹查找

關鍵字:二叉平衡樹,二叉排序樹

在二叉排序樹的不斷插入查找中,有可能出現極端情況,最壞情況例如:

每棵樹都隻有右孩子。那樣查找變成了順序查找了。

為了使排序樹的深度最小,需要對每棵樹的左右孩子進行平衡處理,成為

二叉平衡樹。

二叉平衡樹:它是一棵空樹,或者,它的左孩子或右孩子不為空的話也為

平衡二叉樹。二叉平衡樹的左孩子和右孩子的深度差絕對值不能超過1。

如果将平衡因子設為左子樹的深度減去右子樹的深度,那麼值有-1,0,1。

讨論一下插入結點時的平衡操作。

插入結點可以分為兩種:

一插入根結點,二插入葉子結點。

插入根結點較為簡單,着重看插入葉子結點的情況。

(1)設有樹tree1:

            a(2)                     b(0)

            /    \                     /    \

      b(1)      ar      =>    bl      a(0)

     /    \                          ^      /    \

   bl      br                      c    br     ar

   ^

   c

   或樹tree1':

           a(2)                b(0)

          /                       /    \

      b(1)          =>    bl      a(0)

     /

    ^

    bl

因為插入新結點而使樹的平衡因子變為2,在這種情況下,需要作

單向右旋平衡處理:

b和a交換位置,a接管b的右孩子br,那樣樹就平衡了,并且樹的結點被中

序周遊的順序不變。

(2)設有樹tree2:

          a(-2)                             b(0)

          /    \                               /    \

        al      b(-1)     =>        a(0)     br

                 /     \                  /    \       ^

              bl       br             al      bl    c

                        ^

                        c

   或樹tree2':

           a(-2)                            b(0)

                  \                            /    \

                b(-1)     =>        a(0)     br

                       \

                       ^

                       br

因為插入新結點而使樹的平衡因子變為-2,在這種情況下,需要作

單向左旋平衡處理:

b和a交換位置,a接管b的左孩子bl,那樣樹就平衡了,并且樹的結點被中序

周遊的順序不變。因為不确定bl是否為NULL,是以a的平衡因子不确定。

(3)設有樹tree3:

            a(2)                          a(2)                ____br(0)____

            /    \                           /    \               /                       \

     b(-1)      ar    =>       br(?)      ar   =>  b(?)                 a(?)

     /    \                          /     \                    /    \                 /     \

  bl      br(?)             b(?)    null\d          bl      c\null null\d      ar

           /     \              /    \

   c\null       null\d  bl      c\null

  或樹tree3':

            a(2)                      a(2)               br(0)

            /                           /                     /     \

     b(-1)            =>    br(1)        =>   b(0)       a(0)

           \                     /

           ^               b(0)

           br

因為插入新結點或d結點而使樹的平衡因子變為2,在這種情況下,需要作

雙向旋轉(先左後右)平衡處理:先b和br作單向左旋,然後br和a作單向

右旋,那樣樹就平衡了。并且樹的結點被中序遍的順序不變。

(4)設有樹tree4:

           a(-2)                  a(-2)                     ____bl(0)____

           /    \                    /    \                      /                      \

        al      b(1)  =>    al      bl(?)   =>      a(?)                b(?)

                 /    \                   /     \              /    \                 /    \

          bl(?)      br      c\null       b(?)     al      c\null null\d      br

           /    \                               /    \

    c\null    null\d               null\d      br

   或樹tree4':

           a(-2)               a(-2)                       bl(0)

               \                        \                        /     \

                b(1)  =>            bl(-1)   =>  a(0)       b(0)

               /                             \

              ^                              b(0)

             bl

因為插入新結點或d結點而使樹的平衡因子變為-2,在這種情況下,需要作

雙向旋轉(先右後左)平衡處理:先b和bl作單向右旋,然後br和a作單向

左旋,那樣樹就平衡了。并且樹的結點被中序遍的順序不變。

讨論一下删除結點時的平衡操作。

因為要保持有序性,是以對二叉排序平衡樹的結點的删除操作和對

二叉排序樹的删除操作類似,不過二叉排序平衡樹還需要作平衡操作。

對樹進行中序周遊,就可以得到結點的從小到大的排序,

如果被删結點隻有一棵子樹,直接用子樹取代被删除結點即可。

如果被删結點有兩棵子樹,那麼可以考慮用其前驅或後繼來替代該結點。

在二叉排序樹中假設有這麼一棵樹:                                                      

                         a

                       /   \

                     b       c

                   /   \

                 d       e

               /   \   /   \

              f     g h     i

                   /   \

                  j     k

但在二叉排序平衡樹中不會出現這樣的情況的,因為上面的樹不平衡。

現在標明用前驅代替删除結點,是以現在重新假設有樹:

                                 _a(?)_

                                /          \

                        b(?)              c(?)/null

                      /        \                ^

         d(?)/null          e(?)/null   ...

        /         \                 ^

  f/null      g(?)/null       ...

                  /

            j/null

在上圖中假設c子樹和e子樹的高度能使a樹平衡。

這樣就可以分情況分析b點的删除對樹平衡的影響了。

現在要删除的結點是b,對該樹的中序周遊順序為fdjgb...a...。

(1)如果b隻有左孩子

   很明顯,隻要将b的左孩子直接連接配接到b的前驅,再将b結點删除。

   那麼它此時的a的平衡因子就會減1,a樹的高度也發生了變化,

   此時要回溯到最小不平衡樹,進行平衡調整,因為調整可能導緻

   最小不平衡樹的父節點不平衡,是以要繼續回溯調整,直到根結

   點。增加高度的旋轉操作和降低高度的旋轉操作對稱。單左旋和

   右左旋剛好為對稱操作。

(2)如果b隻有右孩子

   同理,隻要将b的右孩子直接連接配接到b的前驅,在将b結點删除。

   a樹的高度發生變化,然後進行相應的旋轉操作。

(3)如果b的左右孩子均不為空

   同BST樹的删除操作,删除後的樹為:

                                __a(?)__

                               /              \

                       g(?)               c(?)/null

                     /        \                 ^

         d(?)/null          e(?)/null   ...

         /         \               ^

  f/null           j/null       ...

  或當g為空時:

                               __a(?)__

                              /               \

                   __d(?)__           c(?)/null

                  /              \              ^

            f/null          e(?)/null     ...

                                 ^

                                 ...

  由以上看到,發生高度變化的樹有d樹,g樹,a樹。需要進行調整。

  平衡因子的變化:

  如果b的左孩子或右孩子為空,回溯調整a。

  如果g為空,删除b後,則d的平衡因子不變,回溯調整a。

  如果g不為空,删除b後,d的平衡因子加1,回溯調整g和a。

      g的平衡因子取b原來的平衡因子。

      是以樹的平衡調整從d結點開始,到g,再到a。也就是說,

      是在替換删除結點的結點開始平衡調整的。為了代碼友善,

      這種情況就隻是用替換結點的值對删除結點的值進行替換,

      實際删除的結點是替換點(便于程式設計實作回溯)。但平衡

      因子不能被替換。

  源代碼的測試暫未發現錯誤。

附源代碼:

//樹的平衡因子常量
#define LSZ_SEARCH_BALANCEDIFF 1
#define LSZ_SEARCH_LEFTHIGH 1
#define LSZ_SEARCH_EQUALHIGH \
    ((LSZ_SEARCH_LEFTHIGH)-(LSZ_SEARCH_BALANCEDIFF))
#define LSZ_SEARCH_RIGHTHIGH \
    ((LSZ_SEARCH_EQUALHIGH)-(LSZ_SEARCH_BALANCEDIFF))
//樹的高度是否增加
#define LSZ_SEARCH_HIGHERTRUE 1
#define LSZ_SEARCH_HIGHERFALSE 0
//樹的高度是否減少
#define LSZ_SEARCH_LOWERTRUE 1
#define LSZ_SEARCH_LOWERFALSE 0

//删除樹結點的宏
#define LSZ_SEARCH_DESTROYNODE(node) (free((node)->element),free(node))
//初始化樹頭結點的宏
#define LSZ_SEARCH_TREEINIT(tree) ((tree).lChild=NULL)

//元素的關鍵字類型
typedef int LSZ_SearchK; //key

//元素類型
typedef struct LSZ_SearchE{ //element
    LSZ_SearchK key; //元素的鍵值,用于唯一辨別
}LSZ_SearchE;
//帶平衡因子的非順序存儲的查找樹的結構元素類型
//二叉平衡樹的結點類型
typedef struct LSZ_SearchBBTNode{ //binary,balance, tree
    int fBalance; //factor of balance
    LSZ_SearchE *element;
    struct LSZ_SearchBBTNode *lChild;
    struct LSZ_SearchBBTNode *rChild;
}LSZ_SearchBBTNode;
           
//二叉排序平衡樹查找
//
//tree:其左孩子指向樹的根結點。
//element:當往樹中插入結點時,其指向空間存放傳入值,
//          其它情況指向空間用于記錄查找到元素的值。
//mode:僅查找,或帶插入的查找,或帶删除的查找。
int LSZ_search_treeBinarySortedBalanced(LSZ_SearchBBTNode *tree,
                                        LSZ_SearchE *element,
                                        int mode)
{
    int depth = LSZ_SEARCH_HIGHERFALSE; //标記樹的深度的變化
    LSZ_SearchBBTNode *treeTemp = tree->lChild; //取得根結點

    switch(mode){
        case LSZ_SEARCH_ONLY:
            while(treeTemp != NULL){
                if(treeTemp->element->key == element->key){
                    *element = *(treeTemp->element);
                    return 0; //查找成功
                }
                else{
                    treeTemp = element->key < treeTemp->element->key
                        ? treeTemp->lChild : treeTemp->rChild;
                }
            }
            break;
        case LSZ_SEARCH_INSERT: //插入查找需要堆棧
            return LSZ_search_insertBSBT(&(tree->lChild), element, &depth); //這裡沒有初始化右子樹
            break;
        case LSZ_SEARCH_DELETE: //删除查找需要堆棧
            return LSZ_search_deleteBSBT(&(tree->lChild), element, &depth);
            break;
    }
    return -1; //出錯
}
           
//二叉排序平衡樹帶插入的查找
//
//(*tree):指向需要被查找的樹的樹根的指針的位址。
//       注意(*tree)必須在原來的樹結構中并指向樹根。
//element:指向空間存放要插入結點的值,或已存在結點的傳出值。
//isHigher:在執行插入函數後,傳回樹是否長高。
int LSZ_search_insertBSBT(LSZ_SearchBBTNode **tree,
                            LSZ_SearchE *element,
                            int *isHigher)
{
    int result; //記錄調用插入函數的傳回值,判斷是否執行了插入操作

    if((*tree) == NULL){ //空樹
        if((*tree = (LSZ_SearchBBTNode*)malloc(
                sizeof(LSZ_SearchBBTNode))) == NULL){
            return -1;
        }
        if(((*tree)->element = (LSZ_SearchE*)malloc(
                sizeof(LSZ_SearchE))) == NULL){
            free(*tree);
            return -1;
        }
        (*tree)->lChild = (*tree)->rChild = NULL;
        *((*tree)->element) = *element;
        (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH; //新插入結點的平衡因子
        *isHigher = LSZ_SEARCH_HIGHERTRUE; //樹的高度發生變化
        return 1;
    }
    else{ //樹非空
        if((*tree)->element->key == element->key){
            *element = *((*tree)->element);
            *isHigher = LSZ_SEARCH_HIGHERFALSE;
            return 0; //已存在結點,查找成功
        }
        if((*tree)->element->key > element->key){ //往左子樹中插入
            if((result = LSZ_search_insertBSBT(&((*tree)->lChild), element, isHigher)) == -1){
                return -1; //插入失敗
            }
            if(*isHigher == LSZ_SEARCH_HIGHERTRUE){ //左子樹變高,需要修改平衡因子和判斷整棵樹是否長高
                switch((*tree)->fBalance){ //原來樹根的平衡因子
                    case LSZ_SEARCH_LEFTHIGH:
                        LSZ_search_lBalanceBSBT(tree); //需要進行左平衡處理
                        *isHigher = LSZ_SEARCH_HIGHERFALSE;
                        break;
                    case LSZ_SEARCH_EQUALHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_LEFTHIGH;
                        *isHigher = LSZ_SEARCH_HIGHERTRUE;
                        break;
                    case LSZ_SEARCH_RIGHTHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH;
                        *isHigher = LSZ_SEARCH_HIGHERFALSE;
                        break;
                }
            }
        }
        else{ //往右子樹插入
            if((result = LSZ_search_insertBSBT(&((*tree)->rChild), element, isHigher)) == -1){
                return -1; //插入失敗
            }
            if(*isHigher == LSZ_SEARCH_HIGHERTRUE){ //右子樹變高,需要修改平衡因子和判斷整棵樹是否長高
                switch((*tree)->fBalance){ //原來樹根的平衡因子
                    case LSZ_SEARCH_LEFTHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH;
                        *isHigher = LSZ_SEARCH_HIGHERFALSE;
                        break;
                    case LSZ_SEARCH_EQUALHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_RIGHTHIGH;
                        *isHigher = LSZ_SEARCH_HIGHERTRUE;
                        break;
                    case LSZ_SEARCH_RIGHTHIGH:
                        LSZ_search_rBalanceBSBT(tree); //需要進行右平衡處理
                        *isHigher = LSZ_SEARCH_HIGHERFALSE;
                        break;
                }
            }                                                                                         
        }
        return result;
    }
}
           
//二叉排序平衡樹帶删除的查找
//
//(*tree):指向需要被查找的樹的樹根的指針的位址。
//       注意(*tree)必須在原來的樹結構中并指向樹根。
//element:指向空間存放要删除結點的值。
//isHigher:在執行插入函數後,傳回樹是否長高。
int LSZ_search_deleteBSBT(LSZ_SearchBBTNode **tree,
                            LSZ_SearchE *element,
                            int *isLower)
{
    int result; //記錄調用删除函數的傳回值,判斷是否執行了删除操作
    LSZ_SearchBBTNode *nodeDelete, **nodeFind;
    LSZ_SearchE *elementTemp; //用于替換結點和删除結點的交換

    if((*tree) == NULL){ //空樹
        *isLower = LSZ_SEARCH_LOWERFALSE; //樹的高度未發生變化
        return 0;
    }
    else{ //樹非空
        if((*tree)->element->key == element->key){ //找到删除結點
            nodeDelete = *tree;
            *element = *((*tree)->element);
            //下面的删除要按照二叉排序樹的删除方法
            if(nodeDelete->lChild == NULL || nodeDelete->rChild == NULL){
                if(nodeDelete->lChild == NULL){
                    *tree = nodeDelete->rChild;
                    if(*tree != NULL){ //相當于少一右孩子,防止删除根結點平衡因子不更新出錯
                        (*tree)->fBalance += LSZ_SEARCH_BALANCEDIFF;
                    } //因為要操作平衡因子,防止兩結點都為空的情況
                }
                else{ //删除結點無右孩子
                    *tree = nodeDelete->lChild;
                    if(*tree != NULL){ //相當于少一左孩子,防止删除根結點平衡因子不更新出錯
                        (*tree)->fBalance -= LSZ_SEARCH_BALANCEDIFF;
                    } //因為要操作平衡因子,防止兩結點都為空的情況
                }
                *isLower = LSZ_SEARCH_LOWERTRUE; //高度變化
                LSZ_SEARCH_DESTROYNODE(nodeDelete);
                return 1; //删除成功
            }
            else{ //删除結點同時有左右孩子,注意平衡因子的調整
                nodeFind = &(nodeDelete->lChild);
                if((*nodeFind)->rChild == NULL){ //删除結點的後繼的特殊情況
                    *tree = (*nodeFind);
                    (*tree)->fBalance -= 1; //相當于少一左孩子,防止删除根結點平衡因子出錯
                    (*tree)->rChild = nodeDelete->rChild;
                    LSZ_SEARCH_DESTROYNODE(nodeDelete);
                    *isLower = LSZ_SEARCH_LOWERTRUE; //高度變化
                    return 1;
                }
                else{ //删除結點後繼的一般情況
                    while((*nodeFind)->rChild != NULL){
                        (*nodeFind) = (*nodeFind)->rChild;
                    }
                    //删除結點的值賦予替換結點的值,但不包括平衡因子
                    (*nodeFind)->fBalance = nodeDelete->fBalance;
                    elementTemp = nodeDelete->element; //交換元素
                    nodeDelete->element = (*nodeFind)->element;
                    (*nodeFind)->element = elementTemp;
                    goto ToDeleteLChild; //為了利用函數遞歸的堆棧,強制轉跳,最終要删除的結點為替換結點
                } //一般情況
            } //删除結點同時有左右孩子
        } //找到删除結點
        if((*tree)->element->key > element->key){ //往左子樹中删除
ToDeleteLChild:   result = LSZ_search_deleteBSBT(&((*tree)->lChild), element, isLower);
            if(*isLower == LSZ_SEARCH_LOWERTRUE){ //左子樹變矮,需要修改平衡因子和判斷整棵樹是否變矮
                switch((*tree)->fBalance){ //原來樹根的平衡因子
                    case LSZ_SEARCH_LEFTHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH;
                        *isLower = LSZ_SEARCH_LOWERTRUE;
                        break;
                    case LSZ_SEARCH_EQUALHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_RIGHTHIGH;
                        *isLower = LSZ_SEARCH_LOWERFALSE;
                        break;
                    case LSZ_SEARCH_RIGHTHIGH:
                        LSZ_search_rBalanceBSBT(tree); //需要進行右平衡處理
                        *isLower = LSZ_SEARCH_LOWERTRUE;
                        break;
                }
            }
        } //往左子樹删除
        else{ //往右子樹删除
            result = LSZ_search_deleteBSBT(&((*tree)->rChild), element, isLower);
            if(*isLower == LSZ_SEARCH_LOWERTRUE){ //右子樹變矮,需要修改平衡因子和判斷整棵樹是否變矮
                switch((*tree)->fBalance){ //原來樹根的平衡因子
                    case LSZ_SEARCH_LEFTHIGH:
                        LSZ_search_lBalanceBSBT(tree); //需要進行左平衡處理
                        *isLower = LSZ_SEARCH_LOWERTRUE;
                        break;
                    case LSZ_SEARCH_EQUALHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_LEFTHIGH;
                        *isLower = LSZ_SEARCH_LOWERFALSE;
                        break;
                    case LSZ_SEARCH_RIGHTHIGH:
                        (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH;
                        *isLower = LSZ_SEARCH_LOWERTRUE;
                        break;
                }                                                                                        
            }
        } //往右子樹删除
        return result;
    } //樹非空
}
           
//左子樹(長高)導緻失衡時的左平衡調整函數
//
//(*tree):指向最小的失衡樹的樹根。
//       注意(*tree)必須在原來的樹結構中。
void LSZ_search_lBalanceBSBT(LSZ_SearchBBTNode **tree)
{
    LSZ_SearchBBTNode **lChild;

    lChild = &((*tree)->lChild); //最小非平衡樹的左孩子
    switch((*lChild)->fBalance){ //檢查左子樹,确定單向旋轉還是雙旋轉
        case LSZ_SEARCH_LEFTHIGH: //新結點插入在左左孩子上,隻需單向右旋
            (*tree)->fBalance = (*lChild)->fBalance = LSZ_SEARCH_EQUALHIGH;
            LSZ_search_rRotateBSBT(tree); //經過旋轉,(*tree)已改變
            break;
        case LSZ_SEARCH_RIGHTHIGH: //新結點插入在左右孩子上,需要進行雙旋轉
            switch((*lChild)->rChild->fBalance){ //需要判斷和調整平衡因子
                case LSZ_SEARCH_LEFTHIGH: //新結點插入在左右孩子的左孩子上
                    (*tree)->fBalance = LSZ_SEARCH_RIGHTHIGH;
                    (*lChild)->fBalance = LSZ_SEARCH_EQUALHIGH;
                    break;
                case LSZ_SEARCH_EQUALHIGH:
                    (*tree)->fBalance = (*lChild)->fBalance = LSZ_SEARCH_EQUALHIGH;
                    break;
                case LSZ_SEARCH_RIGHTHIGH:
                    (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH;
                    (*lChild)->fBalance = LSZ_SEARCH_LEFTHIGH;
                    break;
            }
            (*lChild)->rChild->fBalance = LSZ_SEARCH_EQUALHIGH;
            LSZ_search_lRotateBSBT(lChild);
            LSZ_search_rRotateBSBT(tree);
            break;
    }
}
           
//右子樹(長高)導緻失衡時的左平衡調整函數
//
//(*tree):指向最小的失衡樹的樹根。
//       注意(*tree)必須在原來的樹結構中。
void LSZ_search_rBalanceBSBT(LSZ_SearchBBTNode **tree)
{
    LSZ_SearchBBTNode **rChild;

    rChild = &((*tree)->rChild); //最小非平衡樹的右孩子
    switch((*rChild)->fBalance){ //檢查左子樹,确定單向旋轉還是雙旋轉
        case LSZ_SEARCH_LEFTHIGH: //新結點插入在右左孩子上,需要進行雙旋轉
            switch((*rChild)->lChild->fBalance){ //需要判斷和調整平衡因子
                case LSZ_SEARCH_LEFTHIGH:
                    (*tree)->fBalance = LSZ_SEARCH_EQUALHIGH;
                    (*rChild)->fBalance = LSZ_SEARCH_RIGHTHIGH;
                    break;
                case LSZ_SEARCH_EQUALHIGH:
                    (*tree)->fBalance = (*rChild)->fBalance = LSZ_SEARCH_EQUALHIGH;
                    break;
                case LSZ_SEARCH_RIGHTHIGH:
                    (*tree)->fBalance = LSZ_SEARCH_LEFTHIGH;
                    (*rChild)->fBalance = LSZ_SEARCH_EQUALHIGH;
                    break;
            }
            (*rChild)->lChild->fBalance = LSZ_SEARCH_EQUALHIGH;
            LSZ_search_rRotateBSBT(rChild);
            LSZ_search_lRotateBSBT(tree);
            break;
        case LSZ_SEARCH_RIGHTHIGH: //新結點插入在右右孩子上,隻需單向左旋
            (*tree)->fBalance = (*rChild)->fBalance = LSZ_SEARCH_EQUALHIGH;
            LSZ_search_lRotateBSBT(tree); //經過旋轉,(*tree)已改變
            break;
    }
}
           
//單向左旋平衡操作函數
//
//(*tree):指向需要旋轉的樹的樹根。
//      注意(*tree)必須在原來的樹結構中并指向樹根。
void LSZ_search_lRotateBSBT(LSZ_SearchBBTNode **tree)
{
    LSZ_SearchBBTNode *axesNode; //旋轉軸結點

    axesNode = (*tree)->rChild; //取得旋轉軸結點
    (*tree)->rChild = axesNode->lChild; //旋轉結點接管軸結點的左孩子
    axesNode->lChild = *tree; //旋轉軸結點指向原根結點
    *tree = axesNode; //旋轉軸作為新根結點
}
           
//單向右旋平衡操作函數
//
//(*tree):指向需要旋轉的樹的樹根。
//      注意(*tree)必須在原來的樹結構中并指向樹根。
void LSZ_search_rRotateBSBT(LSZ_SearchBBTNode **tree)
{   
    LSZ_SearchBBTNode *axesNode; //旋轉軸結點
    
    axesNode = (*tree)->lChild; //取得旋轉軸結點
    (*tree)->lChild = axesNode->rChild; //旋轉結點接管軸結點的右孩子
    axesNode->rChild = *tree; //旋轉軸結點指向原根結點
    *tree = axesNode; //旋轉軸作為新根結點
}
           
//銷毀二叉排序平衡樹
//
//tree:指向樹的頭結點的指針,樹的銷毀用後續周遊。
//     這裡用遞歸實作後根周遊。
void LSZ_search_destroyBSBT(LSZ_SearchBBTNode *tree)
{
    if(tree->lChild != NULL)
        LSZ_search_doDestroyBSBT(tree->lChild);
    tree->lChild = NULL; //重新設定空指向
}
void LSZ_search_doDestroyBSBT(LSZ_SearchBBTNode *tree)
{
    if(tree->lChild != NULL){ //先銷毀左子樹
        LSZ_search_doDestroyBSBT(tree->lChild);
    }
    if(tree->rChild != NULL){ //再銷毀右子樹
        LSZ_search_doDestroyBSBT(tree->rChild);
    }
    //最後銷毀根結點
    LSZ_SEARCH_DESTROYNODE(tree);
}
           

本部落格的版權聲明 點選打開連結

繼續閱讀