分類: 資料結構
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大神關於平衡樹的研究講解 詳細介紹之後會補充的 首先,它的儲存方式和其他的二叉樹類似,都...
方法實現原理 騎縫章列印原理和實現方法大揭秘
騎縫章,顧名思義,就是蓋章時要壓到邊縫。一般用於比較重要的檔案上,和 鋼印 一樣,具有防止在檔案內增減頁碼的作用,保持檔案的完整性。為了實現高效列印和印章安全管理,將印章連同檔案一起列印在紙張上。使所有頁面的印章拼合到一起形成乙個完整的印章,達到與手工蓋章相同的效果。這要求印表機必須具備零邊距列印以...