Treap原理和實現方法

2021-06-22 05:08:47 字數 2302 閱讀 2561

分類: 資料結構

2013-09-07 14:11

320人閱讀收藏 

舉報treap是一棵二叉搜尋樹,只是每個節點多了乙個優先順序fix,對於每個節點,該節點的優先順序小於等於其所有孩子的優先順序。

當然,引入優先順序fix的目的就是防止bst退化成一條鏈,從而影響查詢效率。

所以,這樣看來就是:treap中對於節點的關鍵字key來說,它是一棵二叉搜尋樹,而對於fix來說,它是乙個最小堆,所以

treap可以看成是tree+heap,只是這裡的heap不一定是完全二叉樹。

treap的平均時間複雜度為log(n).

treap跟笛卡爾樹幾乎是一模一樣的,只是用途不同。

笛卡爾樹是把已有的一些(key, fix)二元組拿來構造樹,然後利用構樹過程和構造好的樹來解決lca,rmq等等問題。而

treap的目的只是

對一些key進行二叉搜尋,但是為了保證樹的平衡性,為每個key隨機地額外增加了乙個fix屬性,這樣從概

率上來講可以讓這

棵樹更加平衡。

對於treap來說,主要有幾大操作:插入,刪除,查詢,旋轉,找第k大元素,找關鍵字x的排名,計算treap的高度,刪除

treap,其它的操作比如合併,分離,反轉等等以後再說,另外,對於treap來說,它的中序遍歷的結果就是按照關鍵字從小到

大的順序排列的。

下面用乙個題來看看treap的各種操作。

題目:

題意:給乙個序列,然後給出m個查詢,每次查詢輸入乙個數x,對於第i次查詢,輸出前x個數中第i大的關鍵字的值。

分析:我們可以用其它資料結構解決,這裡我們先學用treap怎麼做吧,方法就是:每次我們都插入前x個數中沒有插過的,當

然程式中我們用index來劃分界限,然後輸出kth(root,i)即可。

[cpp]view plain

copy

#include 

#include 

#include 

#include 

using

namespace

std;  

struct

treap  

intcompare(

intx) 

const

void

maintain()  

};  

void

rotate(treap* &t,

intd)  

void

insert(treap* &t,

intx)  

t->maintain();  

}  //一般來說,在呼叫刪除函式之前要先用find()函式判斷該元素是否存在

void

delete(treap* &t,

intx)  

else

if(t->ch[1]==null)  

else

}  else

delete(t->ch[d],x);  

if(t!=null) t->maintain();  

}  bool

find(treap *t,

intx)  

return

false

;  }  

intkth(treap *t,

intk)  

intrank(treap *t,

intx)  

void

deletetreap(treap* &t)  

void

print(treap *t)  

intval[1000005];  

intmain()  

deletetreap(root);  

}  return

0;  

}  

指標實現 Treap

前置知識 二叉排序樹,堆。應用場景 平衡樹。我們都知道,二叉排序樹就是滿足 lch 左兒子小於根節點,右兒子大於根節點 的二叉樹,一般情況下插入 刪除和搜尋的時間複雜度都為 theta log n 非常快。但在特殊情況下,二叉排序樹可能會退化成鏈,時間複雜度也會變為 theta n 只有當二叉排序樹...

Treap的實現方法 BZOJ 3224

傳說,有一種排序二叉樹叫做treap。而 treap tree heap 所以,treap既具有樹,也具有堆的性質。它的基本操作和普通的樹相近,但也有一些差異。以上全部為亂講系列 如果要看詳細介紹,這裡給出lmy大神關於平衡樹的研究講解 詳細介紹之後會補充的 首先,它的儲存方式和其他的二叉樹類似,都...

方法實現原理 騎縫章列印原理和實現方法大揭秘

騎縫章,顧名思義,就是蓋章時要壓到邊縫。一般用於比較重要的檔案上,和 鋼印 一樣,具有防止在檔案內增減頁碼的作用,保持檔案的完整性。為了實現高效列印和印章安全管理,將印章連同檔案一起列印在紙張上。使所有頁面的印章拼合到一起形成乙個完整的印章,達到與手工蓋章相同的效果。這要求印表機必須具備零邊距列印以...