資料結構之Treap

2021-09-26 04:10:01 字數 2531 閱讀 7063

1. 概述

同splay tree一樣,treap也是乙個平衡二叉樹,不過treap會記錄乙個額外的資料,即優先順序。treap在以關鍵碼構成二叉搜尋樹的同時,還按優先順序來滿足堆的性質。因而,treap=tree+heap。這裡需要注意的是,treap並不是二叉堆,二叉堆必須是完全二叉樹,而treap可以並不一定是。

2. treap基本操作

為了使treap 中的節點同時滿足bst性質和最小堆性質,不可避免地要對其結構進行調整,調整方式被稱為旋轉。在維護treap 的過程中,只有兩種旋轉,分別是左旋轉(簡稱左旋)和右旋轉(簡稱右旋)。

左旋乙個子樹,會把它的根節點旋轉到根的左子樹位置,同時根節點的右子節點成為子樹的根;右旋乙個子樹,會把它的根節點旋轉到根的右子樹位置,同時根節點的左子節點成為子樹的根。

struct treap_node

;void treap_left_rotate(treap_node *&a) //左旋 節點指標一定要傳遞引用

void treap_right_rotate(treap_node *&a) //右旋 節點指標一定要傳遞引用

3. treap的操作同其他樹形結構一樣,treap的基本操作有:查詢,插入,刪除等。

3.1    查詢

同其他二叉樹一樣,treap的查詢過程就是二分查詢的過程,複雜度為o(lg n)。

3.2    插入

在treap 中插入元素,與在bst 中插入方法相似。首先找到合適的插入位置,然後建立新的節點,儲存元素。但是要注意新的節點會有乙個優先順序屬性,該值可能會破壞堆序,因此我們要根據需要進行恰當的旋轉。具體方法如下:

1. 從根節點開始插入;

2. 如果要插入的值小於等於當前節點的值,在當前節點的左子樹中插入,插入後如果左子節點的優先順序小於當前節點的優先順序,對當前節點進行右旋;

3. 如果要插入的值大於當前節點的值,在當前節點的右子樹中插入,插入後如果右子節點的優先順序小於當前節點的優先順序,對當前節點進行左旋;

4. 如果當前節點為空節點,在此建立新的節點,該節點的值為要插入的值,左右子樹為空,插入成功。

treap_node *root;

void treap_insert(treap_node *&p,int value) //節點指標一定要傳遞引用

else if (value <= p->value)

else

}

3.3   刪除與bst 一樣,在treap 中刪除元素要考慮多種情況。我們可以按照在bst 中刪除元素同樣的方法來刪除treap 中的元素,即用它的後繼(或前驅)節點的值代替它,然後刪除它的後繼(或前驅)節點。

上述方法期望時間複雜度為o(logn),但是這種方法並沒有充分利用treap 已有的隨機性質,而是重新得隨機選取代替節點。我們給出一種更為通用的刪除方法,這種方法是基於旋轉調整的。首先要在treap 樹中找到待刪除節點的位置,然後分情況討論:

情況一,該節點為葉節點或鏈節點,則該節點是可以直接刪除的節點。若該節點有非空子節點,用非空子節點代替該節點的,否則用空節點代替該節點,然後刪除該節點。

情況二,該節點有兩個非空子節點。我們的策略是通過旋轉,使該節點變為可以直接刪除的節點。如果該節點的左子節點的優先順序小於右子節點的優先順序,右旋該節點,使該節點降為右子樹的根節點,然後訪問右子樹的根節點,繼續討論;反之,左旋該節點,使該節點降為左子樹的根節點,然後訪問左子樹的根節點,這樣繼續下去,直到變成可以直接刪除的節點。

bst_node *root;

void treap_delete(treap_node *&p,int *value) //節點指標要傳遞引用

else //情況二

else //左子節點修正值較小,左旋

}} else if (value < p->value)

treap_delete(p->left,r); //在左子樹查詢要刪除的節點

else

treap_delete(p->right,r); //在右子樹查詢要刪除的節點

}

4. treap應用treap可以解決splay tree可以解決的所有問題,具體參見另一篇博文:《資料結構之伸展樹》

可以這樣定義結構體:

struct treap_node

//返回左子樹的節點個數

inline int rsize() //返回右子樹的節點個數

};

5. 總結treap 作為一種簡潔高效的有序資料結構,在電腦科學和技術應用中有著重要的地位。它可以用來實現集合、多重集合、字典等容器型資料結構,也可以用來設計動態統計資料結構。

6. 參考資料

(1)treap:

更多關於資料結構和演算法的介紹,請檢視:資料結構與演算法彙總

資料結構 Treap

前兩天看了byvoid大神寫的treap的 中幾乎給出了所有的 不過最後一部提到了乙個優化,就是對於重複的元素採用在同乙個節點中記錄乙個weight來記錄者個元素使用了多少次的寫法,以及查詢第k個數的功能的實現,我試著寫了乙個,表示樹旋轉之後需要重新設定size有一點點煩。因為找不到合適的題目去測試...

模板 資料結構 Treap

還有人把treap叫做樹堆的,但是常用名還是叫做treap的比較多。不進行任何封裝的,帶求和操作的,乙個節點存放多個元素的最普通的treap。includeusing namespace std typedef long long ll define ls ch id 0 define rs ch ...

演算法 資料結構 Treap

treap 完整版 struct treap void pushup int u void rotate int u,int d void inserthelp int u,ll v,ll c else if v val u else pushup u void removehelp int u,l...