1. 程式人生 > >資料結構MOOC|二叉搜尋樹BST

資料結構MOOC|二叉搜尋樹BST

課程內容來自:http://www.icourse163.org/learn/ZJU-93001?tid=1002654021#/learn/content?type=detail&id=1003620986

二叉搜尋樹(BST,Binary Search Tree)

也稱二叉排序樹或二叉查詢樹,

是一棵二叉樹,可以為空;若不為空,則滿足以下性質:

  1. 非空左子樹的所有鍵值小於其根結點的鍵值;
  2. 非空右子樹的所有鍵值大於其根結點的鍵值;
  3. 左、右子樹都是二叉搜尋樹。

【涉及函式】

  • Position Find( ElementType X, BinTree BST):從BST中查詢元素X,返回其所在結點的地址;
  • Position FindMin( BinTree BST):從BST中查詢並返回最小元素所在結點的地址;
  • Position FindMax BinTree BST):從BST中查詢並返回最大元素所在結點的地址;
  • BinTree Insert( ElementType X, BinTree BST )
  • BinTree Delete( ElementType X, BinTree BST )

查詢:

Position Find( ElementType X, BinTree BST)
{
    if( !BST ) return NULL;
    if( X > BST->Data )
        return Find( X, BST->Right);
    else if( X < BST->Data )
        return Find( X, BST->Left);
    else return BST;
    
}
//非遞迴方式執行效率高,將上面的尾遞迴函式改為迭代函式
Position Find( ElementType X, BinTree BST)
{
    while( BST ){
        if( X > BST->Data ) BST = BST->Right;
        else if( X < BST->Data ) BST = BST->Left;
        else return BST;
    }
    return NULL;
}

查詢的效率取決於樹的高度。

Position FindMax( BinTree BST )
{
    if( BST )
        while( BST->Right ) BST = BST->Right;
    return BST;
}
Position FindMin( BinTree BST )
{
    if( !BST ) return NULL;
    else if( !BST->Left) return BST;
    else return FindMin( BST->Left );
}

插入:

BinTree Insert( ElementType X, BinTree BST)
{
    if( !BST ){
        BST = malloc(sizeof(struct TreeNode));
        BST->Data = X;
        BST->Left = BST->Right = NULL;
    }else{
        if( X < BST->Data )
            BST->Left = Insert( X, BST->Left);
        else if( X > BST->Data )
            BST->Right = Insert( X, BST->Right);
    }
    return BST;
}

刪除:

需要考慮三種情況:

  • 刪除的結點沒有兒子結點->直接刪除;
  • 刪除的結點有一個兒子結點;
  • 刪除的結點有兩個兒子結點。
BinTree Delete( ElementType X, BinTree BST)
{
    Position Tmp;
    if( BST==NULL ) cout<<"要刪除的元素未找到"<<endl;
    else if( X < BST->Data )
        BST->Left = Delete( X,BST->Left);
    else if( X > BST->Data )
        BST->Right = Delete( X,BST->Right);
    else{                                         //找到該元素
        if( BST->Left!=NULL && BST->Right!=NULL){ //被刪除結點有兩個非空子節點
            Tmp = FindMin( BST->Right );          //用右子樹的最小結點填充被刪除結點
            BST->Data = Tmp->Data;
            BST->Right = Delete( BST->Data, BST->Right);
        }else{                                    //被刪除結點有一個或無子結點
            Tmp = BST; 
            if( BST->Left==NULL )
                BST = BST->Right;
            else if( BST->Right==NULL)
                 BST = BST->Left;
            free( Tmp );
        }
    return BST;
    }
}