• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            隨筆-80  評論-24  文章-0  trackbacks-0
            二叉查找樹是這樣一種數據結構:它是按二叉樹的結構來組織的,節點除了key域外,還包含有left、right和p指針,分別指向自己的左孩子、右孩子和父親節點。如果兒子或者父親不存在,則該指針置NULL。二叉查找樹又稱為二叉排序樹。
            二叉查找樹中關鍵字的存儲方式總是滿足:
            設x為二叉查找樹中的一個節點,如果y是x的左子樹中的任意一個節點,則key[y] <= key[x];如果y是x的右子樹中的任意一個節點,則key[y] >= key[x]。因此如果對一棵二叉查找樹進行中序遍歷的話那么輸出的結果將是升序排列的。

            一、中序遍歷二叉樹

            其算法是簡單的,遞歸算法如下:

            1 INORDER-TREE-WALK(x)
            2       if x != NULL
            3       then
            4             INORDER-TREE-WALK(left[x])
            5             print key[x]
            6             INORDER-TREE-WALK(right[x])

            定理:如果x是一棵包含n個節點的子樹的根,則調用INORDER-TREE-WALK(x)過程的時間為θ(n)。
            利用遞推公式證明還是相對簡單的,略。

            二、查詢二叉查找樹

            1、查找指定關鍵字k
            給定指向樹根的指針和關鍵字k,返回包含關鍵字k的指針或者NULL,遞歸算法如下:

            1 TREE-SEARCH(x, k)
            2       if x == NULL or k == key[x]
            3       then
            4             return x
            5       if k < key[x]
            6       then
            7             return TREE-SEARCH(left[x], k)
            8       else
            9             return TREE-SEARCH(right[x], k)

            非遞歸版本的算法如下:

            1 INTERATIVE-TREE-SEARCH(x, k)
            2       while x != NULL and k != key[x]
            3       do
            4             if k < key[x]
            5             then
            6                   x = left[x]
            7             else
            8                   x = right[x]
            9       return x

            算法復雜度相同,均為O(h),其中h為樹的高度。

            2、最大關鍵字元素和最小關鍵字元素
            函數TREE-MINIMUM(x)和TREE-MAXIMUM(x)分別返回二叉查找樹的最小關鍵字元素和最大關鍵字元素,思想也是簡單的,沿著二叉查找樹的left指針一直走下去直到left指針為空,則當前節點為最小關鍵字元素;沿著二叉查找樹的right指針一直走下去直到right指針為空,則當前節點為最大關鍵字元素。復雜度也相同,均問O(h)。
            算法如下:

             1 TREE-MINIMUM(x)
             2       while left[x] != NULL
             3       do
             4             x = left[x]
             5       return x
             6 
             7 TREE-MAXIMUM(x)
             8       while right[x] != NULL
             9       do
            10             x = right[x]
            11       return x

            3、前趨與后繼
            當找尋一個二叉查找樹的中序遍歷后繼節點的時候,有下面兩種情況:
            • 如果當前節點的right指針不為NULL,則說明節點有右子樹,由于是中序遍歷,因此當前節點的后繼節點必然是其右子樹中關鍵字值最小的節點,這通過TREE-MINIMUM(right[x])即可得到;
            • 如果當前節點的right指針為NULL,則說明節點沒有右子樹,此時情況稍微有些復雜,可以畫圖理解一下,其實就是如下情況,沿著當前節點的父指針往上走,只要此節點是是其父節點的右孩子,就繼續往上走,直到此節點是其父節點的左孩子或者此節點為空為止,返回此節點的父節點或者NULL。
            用圖形表示如下:

            我們可以看到,如果節點的right[x]為空,則y節點必是x節點的后繼節點,除非不包含符合這一條件的y節點,則x的后繼節點為NULL。
            由此算法如下:

             1 TREE-SUCCESSOR(x)
             2       if right[x] != NULL
             3       then
             4             return TREE-MINIMUM(right[x])
             5       y = p[x]
             6       while y!= NULL and x == right[y]
             7       do
             8             x = y
             9             y = p[y]
            10       return y


            同理,求節點x的前趨類似:
            • 如果當前節點的left指針不為NULL,則說明節點有左子樹,當前節點的前趨節點必然是其左子樹中關鍵字值最大的節點,這通過TREE-MAXIMUM(left[x])即可得到;
            • 如果當前節點的left指針為NULL,則說明節點沒有左子樹,此時為如下情況,沿著當前節點的父指針往上 走,只要此節點是是其父節點的左孩子,就繼續往上走,直到此節點是其父節點的右孩子或者此節點為空為止,返回此節點的父節點或者NULL。
            由此算法如下:

             1 TREE-PREDECCESSOR(x)
             2       if left[x] != NULL
             3       then
             4             return TREE-MAXIMUM(left[x])
             5       y = p[x]
             6       while y != NULL and x == left[y]
             7       do
             8             x = y
             9             y = p[y]
            10       return y

            兩個算法時間復雜度相同,均為O(h)。

            三、二叉查找樹的插入和刪除

            1、插入
            對于二叉查找樹的插入操作,相對簡單,只需要從二叉查找樹的根開始向下查找應該插入的位置即可。這個應該插入的位置必然為一葉子節點的left指針或者right指針指向的空域。算法如下:

             1 TREE-INSERT(T, z)
             2       y = NULL                        //y指向當前節點的父節點
             3       x = root[T]                     //指向當前節點
             4       while x != NULL
             5       do
             6             y = x
             7             if key[z] < key[x]
             8             then
             9                   x = left[x]
            10             else
            11                   x = right[x]
            12       p[z] = y
            13       if y == NULL                  //如果為空樹
            14       then
            15             root[T] == z            //樹根則為z
            16       else if key[z] < key[y]
            17       then
            18             left[y] = z
            19       else
            20             right[y] = z

            算法復雜度為O(h)。

            2、刪除
            對于刪除一個節點,則情況復雜很多,因為刪除操作破壞了二叉查找樹的結構,必須調整樹的結構,仔細觀察發現,不外乎以下三種情況:
            1. 如果要刪除的節點的左右孩子均為空,則直接刪除該節點即可,因為這樣并沒有破壞二叉查找樹的結構;
            2. 如果要刪除的節點只有一個孩子(為左孩子或者右孩子均可),則直接將要刪除節點的父節點的left指針或者right指針指向要刪除節點的孩子節點即可,同時將孩子節點的父指針指向要刪除節點的父節點;
            3. 如果要刪除的節點既有左子樹又有右子樹,則將要刪除節點用其后繼節點替換,并刪除后繼節點即可。
            為此算法如下:

             1 TREE-DELETE(T, z)
             2       if left[z] == NULL or right[z] == NULL
             3       then                                                            //y指向真正需要刪除的節點
             4             y = z                                                     //y要么為要刪除的節點
             5       else
             6             y = TREE-SUCCESSOR(z)                  //y要么為要刪除節點的后繼節點
             7       if left[y] != NULL
             8       then
             9             x = left[y]
            10       else
            11             x = right[y]
            12       if x != NULL
            13       then
            14             p[x] = p[y]
            15       if p[y] == NULL
            16       then
            17             root[T] = x
            18       else if y == left[p[y]]
            19       then
            20             left[p[y]] = x
            21       else
            22             right[p[y]] = x
            23       if y != z
            24       then
            25             key[z] = key[y]
            26       return y

            時間復雜度同樣為O(h)。

            四、隨機構造的二叉查找樹性能分析
            posted on 2011-10-31 16:28 myjfm 閱讀(340) 評論(0)  編輯 收藏 引用 所屬分類: 算法基礎
            久久99精品久久久久婷婷| 婷婷综合久久狠狠色99h| 久久国产成人精品国产成人亚洲| 91久久精一区二区三区大全| 久久精品国产秦先生| 中文字幕无码久久人妻| 无码精品久久久久久人妻中字| 久久免费的精品国产V∧ | 亚洲国产精品无码久久九九| 久久综合亚洲色HEZYO国产| 久久精品国产亚洲AV麻豆网站 | 久久久久亚洲精品日久生情| 久久久久人妻精品一区| 精品久久久久中文字幕一区| 一本一本久久A久久综合精品| 中文精品99久久国产| 久久精品九九亚洲精品| 一本色道久久88综合日韩精品| 日本欧美久久久久免费播放网 | 久久精品国产免费观看 | 久久精品人人做人人爽电影| 97久久天天综合色天天综合色hd| 久久精品女人天堂AV麻| 久久综合丁香激情久久| 亚洲va久久久噜噜噜久久天堂| 国产伊人久久| 欧美精品一区二区精品久久| 五月丁香综合激情六月久久| 日韩美女18网站久久精品| 久久精品国产一区二区电影| 久久亚洲综合色一区二区三区| 久久香蕉超碰97国产精品| 久久久久久精品免费免费自慰| 久久影院久久香蕉国产线看观看| 国产V亚洲V天堂无码久久久| 色综合久久综合中文综合网| 久久无码高潮喷水| 亚洲国产欧美国产综合久久| 精品伊人久久大线蕉色首页| 思思久久精品在热线热| 久久亚洲sm情趣捆绑调教|