資料結構之伸展樹_資料結構

來源:互聯網
上載者:User
1、 概述

二叉尋找樹(Binary Search Tree,也叫二叉排序樹,即Binary Sort Tree)能夠支援多種動態集合操作,它可以用來表示有序集合、建立索引等,因而在實際應用中,二叉排序樹是一種非常重要的資料結構。

從演算法複雜度角度考慮,我們知道,作用於二叉尋找樹上的基本操作(如尋找,插入等)的時間複雜度與樹的高度成正比。對一個含n個節點的完全二叉樹,這些操作的最壞情況已耗用時間為O(log n)。但如果因為頻繁的刪除和插入操作,導致樹退化成一個n個節點的線性鏈(此時即為一個單鏈表),則這些操作的最壞情況已耗用時間為O(n)。為了克服以上缺點,很多二叉尋找樹的變形出現了,如紅/黑樹狀結構、AVL樹,Treap樹等。

本文介紹了二叉尋找樹的一種改進資料結構–伸展樹(Splay Tree)。它的主要特點是不會保證樹一直是平衡的,但各種操作的平攤時間複雜度是O(log n),因而,從平攤複雜度上看,二叉尋找樹也是一種平衡二叉樹。另外,相比於其他樹狀資料結構(如紅/黑樹狀結構,AVL樹等),伸展樹的空間要求與編程複雜度要小得多。

2、 基本操作

伸展樹的出發點是這樣的:考慮到局部性原理(剛被訪問的內容下次可能仍會被訪問,尋找次數多的內容可能下一次會被訪問),為了使整個尋找時間更小,被查頻率高的那些節點應當經常處於靠近樹根的位置。這樣,很容易得想到以下這個方案:每次尋找節點之後對樹進行重構,把被尋找的節點搬移到樹根,這種自調整形式的二叉尋找樹就是伸展樹。每次對伸展樹進行操作後,它均會通過旋轉的方法把被訪問節點旋轉到樹根的位置。

為了將當前被訪問節點旋轉到樹根,我們通常將節點自底向上旋轉,直至該節點成為樹根為止。“旋轉”的巧妙之處就是在不打亂數列中資料大小關係(指中序遍曆結果是全序的)情況下,所有基本操作的平攤複雜度仍為O(log n)。

伸展樹主要有三種旋轉操作,分別為單旋轉,一字形旋轉和之字形旋轉。為了便於解釋,我們假設當前被訪問節點為X,X的父親節點為Y(如果X的父親節點存在),X的祖父節點為Z(如果X的祖父節點存在)。

(1)    單旋轉

節點X的父節點Y是根節點。這時,如果X是Y的左孩子,我們進行一次右旋操作;如果X 是Y 的右孩子,則我們進行一次左旋操作。經過旋轉,X成為二叉尋找樹T的根節點,調整結束。

(2)    一字型旋轉

節點X 的父節點Y不是根節點,Y 的父節點為Z,且X與Y同時是各自父節點的左孩子或者同時是各自父節點的右孩子。這時,我們進行一次左左旋轉操作或者右右旋轉操作。

(3)    之字形旋轉

節點X的父節點Y不是根節點,Y的父節點為Z,X與Y中一個是其父節點的左孩子而另一個是其父節點的右孩子。這時,我們進行一次左右旋轉操作或者右左旋轉操作。

3、伸展樹區間操作

在實際應用中,伸展樹的中序遍曆即為我們維護的數列,這就引出一個問題,怎麼在伸展樹中表示某個區間。比如我們要提取區間[a,b],那麼我們將a前面一個數對應的結點轉到樹根,將b 後面一個結點對應的結點轉到樹根的右邊,那麼根右邊的左子樹就對應了區間[a,b]。原因很簡單,將a 前面一個數對應的結點轉到樹根後, a 及a 後面的數就在根的右子樹上,然後又將b後面一個結點對應的結點轉到樹根的右邊,那麼[a,b]這個區間就是下圖中B所示的子樹。

利用區間操作我們可以實現線段樹的一些功能,比如回答對區間的詢問(最大值,最小值等)。具體可以這樣實現,在每個結點記錄關於以這個結點為根的子樹的資訊,然後詢問時先提取區間,再直接讀取子樹的相關資訊。還可以對區間進行整體修改,這也要用到與線段樹類似的延遲標記技術,即對於每個結點,額外記錄一個或多個標記,表示以這個結點為根的子樹是否被進行了某種操作,並且這種操作影響其子結點的資訊值,當進行旋轉和其他一些操作時相應地將標記向下傳遞。

與線段樹相比,伸展樹功能更強大,它能解決以下兩個線段樹不能解決的問題:

(1) 在a後面插入一些數。方法是:首先利用要插入的數構造一棵伸展樹,接著,將a 轉到根,並將a 後面一個數對應的結點轉到根結點的右邊,最後將這棵新的子樹掛到根右子結點的左子結點上。

(2)  刪除區間[a,b]內的數。首先提取[a,b]區間,直接刪除即可。

4、實現

代碼全部來自【參考資料2】。

(1)旋轉操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 // node 為結點類型,其中ch[0]表示左結點指標,ch[1]表示右結點指標   // pre 表示指向父親的指標   // Rotate函數用於(左/右)旋轉x->pre   void Rotate(node *x, int d) // 旋轉操作,d=0 表示左旋,d=1 表示右旋

聯繫我們

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