Treap樹的基本操作

2021-07-04 11:56:11 字數 2860 閱讀 1800

3. treap的操作

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

3.1    查詢

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

3.2    插入

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

1. 從根節點開始插入;

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

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

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

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

32

33

34

35

36

37

38

39

40

41

42

43

treap_node *root;

voidtreap_insert(treap_node *&p,intvalue)//節點指標一定要傳遞引用 p為要插入樹的根節點

elseif(value <= p->value)

else

}

3.3:刪除

跟普通的二叉查詢樹一樣,刪除結點存在三種情況。

①:葉子結點

跟普通查詢樹一樣,直接釋放本節點即可。

②:單孩子結點

跟普通查詢樹一樣操作。

③:滿孩子結點

其實在treap中刪除滿孩子結點有兩種方式。

第一種:跟普通的二叉查詢樹一樣,找到「右子樹」的最左結點(15),拷貝元素的值,但不拷貝元素的優先順序,然後在右子樹中

刪除「結點15」即可,最終效果如下圖。

第二種:將」結點下旋「,直到該節點不是」滿孩子的情況「,該賦null的賦null,該將孩子結點頂上的就頂上,如下圖:

當然從理論上來說,第二種刪除方法更合理,這裡我寫的就是第二種情況的**。

1

#region 刪除當前樹中的節點

2///

3///

刪除當前樹中的節點

4///

5///

6///

7public

void

remove(k key, v value)811

#endregion

1213

#region 刪除當前樹中的節點

14///

15///

刪除當前樹中的節點

16///

17///

18///

19///

20public treapnoderemove(k key, v value, treapnodetree)

2130

//右子樹

31if (key.compareto(tree.key) > 0)32

35/*

相等的情況

*/36

if (key.compareto(tree.key) == 0)37

44else

4554

else

5559

60//

繼續旋轉

61 tree =remove(key, value, tree);62}

63else

6472}73

}7475return

tree;76}

77#endregion

Treap實現的名次樹

1.感覺之前邵叔叔教的做fib的那個支援刪除 其實刪除只是打標記,而且不支援插入。和查詢的排序二叉樹就是個靜態的名次樹嘛。我居然學到了這麼奇怪的資料結構。2.寫的時候坑了幾次 1 不要亂用引用,getkth裡那個引數o沒過腦子用了引用,結果把樹搞爛了,一堆ch x 賦值成null了。2 寫查詢的時候...

線段樹套Treap

題目為bzoj1901.單點修改區間第k大,如果卡記憶體你要怎麼辦 hq說線段樹套平衡樹比樹狀陣列套線段樹好得多 所以我就寫了 然後就寫了 n log 3n 在zju上t掉了qaq 卡記憶體還卡時間真是有夠過分 其實就是外層線段樹存一下根然後按照正常的treap寫就好了,但是有乙個問題就是treap...

平衡樹之Treap

乙個集合支援快速插入 刪除乙個數字。支援快速查詢乙個數字在所有已插入數字中的排名。支援刪除大小在某乙個區間內的數字。動態維護乙個數列。可以在數列的任何位置插入刪除,求區間和,min,max,進行區間翻轉 這就需要用到二叉查詢樹 binary search tree 性質 這是一棵二叉樹。對於任意乙個...