(當個日記記錄treap這一結構,詳細參見http://www.nocow.cn/index.php/treap, 在這裡我著重講一下旋轉)
treap,它其它就是乙個二叉查詢樹(bst)+堆(heap). 它的資料有兩個:關鍵值(key),優先順序(fix).
用struct表示treap的結點的結構如下:
struct node
datatype key;
int fix;
node * left;
node * right;
treap的key值滿足bst的性質:即任乙個treap的結點x,若y是x的左子樹,則y.key<=x.key,若y為x的右子樹,則y.key>=x.key.
同時treap的fix滿足heap的性質(在這裡以最大堆為例):即任乙個treap的結點x,若y為x的左子樹或右子樹,則x.fix>=y.fix.
如下圖所示則為treap
treap的作用:它的作用同bst一樣,引入優先順序這一概念是為了防止bst退化成一鍊錶(bst的建立依籟於結點的插入順序,當有序的插入時,則bst為一鍊錶,其它查詢插入的複雜度o(n)),當然我們完全可以隨機的插入結點,但是有時候我們事先並不知道所有結點,在這種情況下我們可以採用treap,即當需要插入的乙個新的key值,我們可以隨機的生成乙個優先順序(fix),然後通過fix約束treap,從而達到隨機生成bst的目的.
為了插入和刪除之後仍然保持treap的兩個性質,在這裡treap提供了兩種旋轉的操作,右旋和左旋
(1)結點右旋
:node x,
令y=x->left; 先將y
的右子樹作為
x的左子樹
,然後將x作為
y的右子樹
, 最後將y作為
x原父結點的子樹(原
x為左子樹,此時
y仍然為左子樹
,x為右子樹
,y也為右子樹
)如下圖所示.
由上可見
,旋轉操作之後仍然滿足
bst的特性
,但是改變
heap
的性質.
插入操作
:有了旋轉操作後
,插入變得十分簡單
.它只需要將結點
(key,fix)
按bst
插入到treap,
此時若不滿足
heap
的性質,
若結點x
的左子樹的
fix大於x的
fix,
則只需要左旋
,若結點
y的右子樹的
fix值大於x的
fix,
則左旋.
直至滿足
heap
的性質.
刪除操作
:只需要將刪除的結點旋轉至葉結點
,直接插除即可.
對於其它的查詢,後繼
,最小值等操作均同
bst一樣
,在這裡便不再詳述.附有
c++ treap實現.
Treap 簡單的平衡二叉搜尋樹
它基本的支援一下操作 1.插入x數 2.刪除x數 若有多個相同的數,只刪除乙個 3.查詢x數的排名 若有多個相同的數,輸出最小的排名 4.查詢排名為x的數 5.求x的前驅 前驅定義為小於x,且最大的數 6.求x的後繼 後繼定義為大於x,且最小的數 模板如下 include include 有rand...
二叉搜尋樹 二叉搜尋樹
題目 二叉搜尋樹 time limit 2000 1000 ms j a others memory limit 32768 32768 k j a others total submission s 6945 accepted submission s 3077 problem descripti...
二叉搜尋樹 修剪二叉搜尋樹
第一反應是重構,看來別人的解答發現,其實不用重構那麼複雜。treenode trimbst treenode root,int low,int high if root val high 下一層處理完左子樹的結果賦給root left,處理完右子樹的結果賦給root right。root left ...