Splay伸展樹&模板__function

來源:互聯網
上載者:User

伸展樹操作詳解 http://wenku.baidu.com/view/cc211f126edb6f1aff001f16.html?from=rec&pos=4&weight=9&lastweight=9&count=5

The Magical Splay http://wenku.baidu.com/view/a202e27931b765ce05081416.html

BST 拓展與伸展樹 (Splay) 一日通 http://wenku.baidu.com/view/f3fbe687b9d528ea81c779b6.html?from=rec&pos=4&weight=10&lastweight=10&count=5

********************************************************************************我是分割線*****************************************************************************************************************

一、簡介:
伸展樹,或者叫自適應尋找樹,是一種用於儲存有序集合的簡單高效的資料結構。伸展樹實質上是一個二叉尋找樹。允許尋找,插入,刪除,刪除最小,刪除最大,分割,合并等許多操作,這些操作的時間複雜度為O(logN)。由於伸展樹可以適應需求序列,因此他們的效能在實際應用中更優秀。
伸展樹支援所有的二叉樹操作。伸展樹不保證最壞情況下的時間複雜度為O(logN)。伸展樹的時間複雜度邊界是均攤的。儘管一個單獨的操作可能很耗時,但對於一個任意的操作序列,時間複雜度可以保證為O(logN)。

二、自調整和均攤分析:
    平衡尋找樹的一些限制:
1、平衡尋找樹每個節點都需要儲存額外的資訊。
2、難於實現,因此插入和刪除操作複雜度高,且是潛在的錯誤點。
3、對於簡單的輸入,效能並沒有什麼提高。
    平衡尋找樹可以考慮提高效能的地方:
1、平衡尋找樹在最差、平均和最壞情況下的時間複雜度在本質上是相同的。
2、對一個節點的訪問,如果第二次訪問的時間小於第一次訪問,將是非常好的事情。
3、90-10法則。在實際情況中,90%的訪問發生在10%的資料上。
4、處理好那90%的情況就很好了。
三、均攤時間邊界:
在一顆二叉樹中訪問一個節點的時間複雜度是這個節點的深度。因此,我們可以重構樹的結構,使得被經常訪問的節點朝樹根的方向移動。儘管這會引入額外的操作,但是經常被訪問的節點被移動到了靠近根的位置,因此,對於這部分節點,我們可以很快的訪問。根據上面的90-10法則,這樣做可以提高效能。
為了達到上面的目的,我們需要使用一種策略──旋轉到根(rotate-to-root)。具體實現如下:
旋轉分為左旋和右旋,這兩個是對稱的。圖示:
 
為了敘述的方便,上圖的右旋叫做X繞Y右旋,左旋叫做Y繞X左旋。
下圖展示了將節點3旋轉到根:
 
                            圖1
首先節點3繞2左旋,然後3繞節點4右旋。
注意:所尋找的資料必須符合上面的90-10法則,否則效能上不升反降。。
四、基本的自底向上伸展樹:
    應用伸展(splaying)技術,可以得到對數均攤邊界的時間複雜度。
    在旋轉的時候,可以分為三種情況:
1、zig情況。
    X是尋找路徑上我們需要旋轉的一個非根節點。
    如果X的父節點是根,那麼我們用下圖所示的方法旋轉X到根:
     
                                圖2
    這和一個普通的單旋轉相同。
2、zig-zag情況。
在這種情況中,X有一個父節點P和祖父節點G(P的父節點)。X是右子節點,P是左子節點,或者反過來。這個就是雙旋轉。
先是X繞P左旋轉,再接著X繞G右旋轉。
如圖所示:
 
                            圖三
3、zig-zig情況。
    這和前一個旋轉不同。在這種情況中,X和P都是左子節點或右子節點。
    先是P繞G右旋轉,接著X繞P右旋轉。
    如圖所示:
     
                                    圖四
    下面是splay的虛擬碼:
    P(X) : 獲得X的父節點,G(X) : 獲得X的祖父節點(=P(P(X)))。
    Function Buttom-up-splay:
        Do
            If X 是 P(X) 的左子結點 Then
                If G(X) 為空白 Then
                    X 繞 P(X)右旋
                Else If P(X)是G(X)的左子結點
                    P(X) 繞G(X)右旋
                    X 繞P(X)右旋
                Else
                    X繞P(X)右旋
                    X繞P(X)左旋 (P(X)和上面一句的不同,是原來的G(X))
                Endif
            Else If X 是 P(X) 的右子結點 Then
                If G(X) 為空白 Then
                    X 繞 P(X)左旋
                Else If P(X)是G(X)的右子結點
                    P(X) 繞G(X)左旋
                    X 繞P(X)左旋
                Else
                    X繞P(X)左旋
                    X繞P(X)右旋 (P(X)和上面一句的不同,是原來的G(X))
                Endif 
            Endif
        While (P(X) != NULL)
    EndFunction
    仔細分析zig-zag,可以發現,其實zig-zag就是兩次zig。因此上面的代碼可以簡化:
    Function Buttom-up-splay:
        Do
            If X 是 P(X) 的左子結點 Then
                If P(X)是G(X)的左子結點
                    P(X) 繞G(X)右旋
                Endif
                X 繞P(X)右旋
            Else If X 是 P(X) 的右子結點 Then
                If P(X)是G(X)的右子結點
                    P(X) 繞G(X)左旋
                Endif 
                X 繞P(X)左旋
            Endif
        While (P(X) != NULL)
    EndFunction
    下面是一個例子,旋轉節點c到根上。 
 
                                    圖五
五、基本伸展樹操作:
1、插入:
    當一個節點插入時,伸展操作將執行。因此,新插入的節點在根上。
2、尋找:
    如果尋找成功(找到),那麼由於伸展操作,被尋找的節點成為樹的新根。
如果尋找失敗(沒有),那麼在尋找遇到NULL之前的那個節點成為新的根。也就是,如果尋找的節點在樹中,那麼,此時根上的節點就是距離這個節點最近的節點。
3、尋找最大最小:
        尋找之後執行伸展。
4、刪除最大最小:
a)刪除最小:
    首先執行尋找最小的操作。
這時,要刪除的節點就在根上。根據二叉尋找樹的特點,根沒有左子節點。
使用根的右子結點作為新的根,刪除舊的包含最小值的根。
b)刪除最大:
首先執行尋找最大的操作。
刪除根,並把被刪除的根的左子結點作為新的根。
5、刪除:
        將要刪除的節點移至根。
        刪除根,剩下兩個子樹L(左子樹)和R(右子樹)。
        使用DeleteMax尋找L的最大節點,此時,L的根沒有右子樹。
        使R成為L的根的右子樹。
        如下圖示:
         
                                圖六
六、自頂向下的伸展樹:
    在自底向上的伸展樹中,我們需要求一個節點的父節點和祖父節點,因此這種伸展樹難以實現。因此,我們可以構建自頂向下的伸展樹。
    當我們沿著樹向下搜尋某個節點X的時候,我們將搜尋路徑上的節點及其子樹移走。我們構建兩棵臨時的樹──左樹和右樹。沒有被移走的節點構成的樹稱作中樹。在伸展操作的過程中:
1、當前節點X是中樹的根。
2、左樹L儲存小於X的節點。
3、右樹R儲存大於X的節點。
開始時候,X是樹T的根,左右樹L和R都是空的。和前面的自下而上相同,自上而下也分三種情況:
1、zig:
 
                                圖七
    如上圖,在搜尋到X的時候,所尋找的節點

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.