數據結構(34)二叉排序樹

目錄

1、二叉排序樹(BST,Binary Sort Tree)定義

2、二叉排序樹的查找

3、二叉排序樹的插入

4、二叉排序樹的構造

5、二叉排序樹的刪除

6、二叉排序樹的查找效率分析

7、二叉排序樹與二分排序對比


1、二叉排序樹(BST,Binary Sort Tree)定義

二叉排序樹(也稱爲二叉查找樹)或者是一棵空樹,或者是具有以下特性的二叉樹:

1)若左子樹非空,則左子樹上所有結點的值均小於根節點的值。

2)若右子樹非空,則右子樹上所有結點的值均大於根節點的值。

3)左、右子樹也分別是一棵二叉排序樹。

根據二叉排序樹的定義,左子樹結點值<根節點值<右子樹結點值,所以對二叉排序樹進行中序遍歷,可以得到一個遞增的有序序列。例如,圖34-1所示的二叉排序樹的中序遍歷序列爲123468。

          圖34-1  二叉排序樹

2、二叉排序樹的查找

二叉排序樹的查找是從根節點開始,沿某個分支逐層向下比較的過程(有沒有感覺一股濃濃的二分法的氣息迎面而來)。若二叉排序樹非空,先將給定值與根節點的關鍵字比較,若相等,則查找成功;若不相等,如果小於根節點的關鍵字,則在根節點的左子樹上查找。

二叉排序樹的非遞歸查找算法:

BSTNode *BST_Search(BiTree T,ElemType key)
{
    while(T != NULL && key != T->data)
    {
        if(key < T->data)
            T = T->lchild;
        else
            T = T->rchild;
    }
    return T;
}

3、二叉排序樹的插入

二叉排序樹作爲一種動態樹表,其特點是樹的結構通常不是一次生成的,而是在查找過程中,當樹中不存在關鍵字值等於給定值的結點時再進行插入的。

插入結點的過程如下:若原二叉排序樹爲空,則直接插入結點;否則,若關鍵字k小於根節點值,則插入左子樹,若關鍵字k大於根節點值,則插入右子樹。插入的結點一定是一個新添加的葉節點,且是查找失敗時的查找路徑上訪問的最後一個結點的左孩子或者右孩子。如圖5.22所示在一個二叉排序樹中一次插入結點28和結點58,虛線表示的邊是其查找路徑。

                                   圖34-1  向二叉排序樹中插入結點

二叉排序樹中插入操作的算法如下:

int BTSInsert(BiTree &T,DataType k)
{
    if(!T)
    {
        T = (BiTree)malloc(sizeof(BSTNode));
        T->data= k;
        T->lchild = NULL;
        T->rchild = NULL;
        return 1;
    } 
    Bitree p = T;   
    else if(k == T->data)
        return 0;
    else if(k < T->data)
        return BTSInsert(T->lchild,k);
    else if(k > T->data)
        return BTSInsert(T->rchild,k);
}

4、二叉排序樹的構造

從一顆空樹出發,一次輸入元素,將他們插入到二叉排序樹中合適的位置。設查找的關鍵字序列爲{45,24,53,45,12,24},則生成的二叉排序樹如圖34-2所示。

                                                             圖34-2  二叉排序樹的構造過程

算法實現我就不用寫了吧,就是遍歷關鍵字序列,每個關鍵字序列調用二叉排序樹中插入操作算法。

5、二叉排序樹的刪除

在二叉排序樹中刪除一個結點時,不能把以該結點爲根的子樹上的結點都刪除,必須先把被刪除結點從存儲二叉排序樹的鏈表上

摘下,將因刪除結點而斷開的二叉鏈表重新鏈接起來,同時確保二叉排序樹的性質不會改變。

刪除操作按3種情況來處理:

①若被刪除結點z是葉節點,則直接刪除,不會破壞二叉排序樹的性質。

②若結點z只有一棵左子樹或右子樹,則讓z的子樹直接成爲z父結點的子樹,代替z的位置。

③若結點z有左右兩棵子樹:

  1. 可以用右子樹的最小元素
  2. 或者左子樹的最大元素來替代被刪除的節點

                            

思考一個問題,就是刪除這個78的時候,不止81可以符合佔據原位置,65也可以,所以二叉排序樹插入的位置變動是唯一的,刪除就不一定了。所以同一個元素的一插一刪會有可能改變原排序二叉樹的形狀,但是性質不會變。

6、二叉排序樹的查找效率分析

二叉排序樹的查找效率,主要取決於樹的高度。若二叉排序樹的左右子樹高度之差不超過1,則這樣的二叉排序樹稱爲平衡二叉樹,它的平均查找長度爲O(log2(n))。若而二叉排序樹是一個只有左(右)孩子的單支樹(類似於有序的單鏈表),則其平均查找長度爲O(n)。

在最壞的情況下,即構造二叉樹的輸入序列是有序的,則會形成一個傾斜的單枝樹,此時二叉排序樹的性能顯著變壞,樹的高度也等於元素個數n,如圖34-3所示。

                                 圖34-3 相同關鍵字組成的不同排序二叉樹

7、二叉排序樹與二分排序對比

從查找過程來看,二叉排序樹與二分查找相似,就平均時間性能而言,二叉排序樹上的查找和二分查找差不多。但二分查找的判定樹唯一,而二叉樹排序樹的查找不唯一,相同關鍵字其插入順序不同可能生出不同的二叉排序樹。如圖34-3所示。

就平均時間性能而言,二叉排序樹上的查找和二分查找差不多。

就表的有序性而言,二叉排序樹無須移動結點,只需修改指針即可完成插入和刪除操作,且其平均的執行時間均爲O(lgn),因此更有效。

二分查找所涉及的有序表是一個向量,若有插入和刪除結點的操作,則維護表的有序性所花的代價是O(n)。

當有序表是靜態查找表時,宜用向量作爲其存儲結構,而採用二分查找實現其查找操作;若有序表裏動態查找表,則應選擇二叉排序樹作爲其存儲結構。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章