伸展樹 (自頂向下的設計)

2021-08-01 22:13:11 字數 3009 閱讀 9093

伸展樹的設計有兩種設計模式,第一種 自低向上的設計方式,第二種 設計方式 自頂向下的設計方式,對於由低向上的設計,每乙個結點樹保留指向其父結點的的額外的結點, 第二種方式由sedgewick

大神的《演算法》一書感謝這一

位大神。

伸展樹又叫自適應查詢樹,實質上二叉搜尋樹的的變形,允許各種型別的二叉樹操作,操作的時間複雜度

o(logn),但是伸展樹並不能保障最壞的情況,這個時間複雜度是平均的值,適合任意的操作序列。

當我們沿著樹向下搜尋某乙個結點x時候,將搜尋路徑上的結點及其子樹進行移走---建立兩個空樹 左樹和右

樹,沒有被移走的結點叫做中樹,在伸展操作的過程中:

1.當前遍歷結點x 是樹的中樹

2.左樹l保留小於x的結點

3. 右樹r 保留大於x的結點

樹開始遍歷時候 x 是 樹的根t,l,r是空樹,自上而下有三種模式:

1. zig 情況(單旋):

如下圖,在搜尋到x,要查詢的結點比x 小,並且 所查詢結點y剛好等於 所查詢的點 這種方式其實可以合併在zigzag情況之中,最簡單的情況,程式 y 所查詢的結點,y 只需進行簡單的單旋,y 變成新中樹的樹根,x 連線到右樹上。

2. zig-zig (一字型旋轉):

所需要查詢結點 比當前節點 x的孩子結點y值還需要小,對 x進行 左旋操作 ,回到zig情況 之後將左旋 x,y及

其子樹結點 連線到右子樹上。

首先是y繞x右旋,然後將z變成新的中樹根節點。將y及其子樹移到右樹中。注意右樹中掛載點的位置。

3. zig-zag 旋轉(之字型旋轉):

先將y 右旋到 根 ,祖父結點x及其子樹連線右樹,變成圖三的 zag情況,接下 對z 進行左旋變成zig情況,將父結點y鏈結到左樹 上 ,zig-

zag情況需要分分解成兩個zig ;

4. 合併:

所查詢的結點x 已經找到,x ,l,r 合併,x 是合併新樹的樹根,l 比x結點小的 結點集合,r是比x大結點的集合,如果x 有左子樹和右子樹的話

l.right=x.left (x 的子樹結點 還是在 左樹l的右邊,

左樹上點 都是右旋形成

),r.left=x.right

右連線:將當前根以及右子樹連線到 右 樹上 ,當前節點 左子樹結點 作為新根(下一次遍歷的當前節點);

區域性變數 lefttreemax。righttreemin 為了跟隨向下遍歷 時候 增加 左 右 樹長度

/** 伸展樹

* nullpoint 表示邏輯上的null

* 建立空樹 左 樹 和 右 樹

*/

public class splaytree >

public binarynode(anytype element, binarynodeobject, binarynodeobject2)

} private binarynoderoot;

private binarynodenullnode;

// for splay 記錄 左樹 和右樹的首位址

private binarynodeheader=new binarynode(null);

// use between different inserts

private binarynodenewnode=null;

/** 自頂向下的伸展時候

* 建立 兩個空樹 */

private binarynodesplay(anytype x,binarynodet)

else if(x.compareto(t.element)>0)

}else

// 找到之後合併

lefttreemax.right=t.left;

righttreemin.left=t.right;

// header 結點 記錄 右樹 最開始位址 ,header 的左子樹 記錄比所查詢點 大的結點 由 righttreemin.left=t

t.left=header.right;

t.right=header.left;

return t;

} }/**

* 將 插入 x 做成 新根 每插入 一次 進行splay*/

public void insert(anytype x)

else // 圍繞新插入值 x 伸展開展開 root ,root。left 伸展開 之後 值一定比x小,已經存在 不insert

else if(x.compareto(root.element)>0)

else

} }/**查詢目標經過旋轉 到 中間派*/

private binarynoderoatewithleftchild(binarynodek1)

private binarynoderoatewithrightchild(binarynodek2)

}

《DSAA》 12 1 自頂向下伸展樹

在許多應用中,當乙個節點被訪問後,馬上就很可能再次被訪問到,研究表明這種情況比人們預料的要頻繁的多。所以伸展樹的基本想法是 當乙個節點被訪問後,它就要通過一系列的旋轉被放到根上。自頂向下伸展樹的搜尋方式非常獨特,它實際上是乙個拆了又裝的過程,這個過程被稱為伸展 最開始先新建兩顆空樹 l樹和r樹,用於...

自底向上和自頂向下

動態規劃的式子都是狀態p由狀態q1 q2 q3 之中選擇乙個或幾個計算出來的形式,但是如果一直是一些狀態這樣遞迴下去,最後會無限迴圈的,所以每個式子一直寫下去最後都會得到一些狀態p是常數 遞迴邊界 的形式。以上可構造乙個dag 自底向上就是已經知道了所有遞迴邊界,把所有可能的狀態都算出來。基本步驟是...

自頂向下,逐項求精

自上而下設計法從裝配體中開始設計工作,這是兩種設計方法的不同之處。您可以使用乙個零件的幾何體來幫助定義另乙個零件,或生成組裝零件後才新增的加工特徵。您可以將布局草圖作為設計的開端,定義固定的零件位置 基準面等,然後參考這些定義來設計零件。例如,您可以將乙個零件插入到裝配體中,然後根據此零件生成乙個夾...