Day2平衡樹筆記

自為風月馬前卒發表於2017-10-29

線段樹不支援的操作:刪除,插入


 

常見的平衡樹

treap 慢||好寫

sbt(大小平衡的樹) 非常快 比較好寫 ||功能不全

rbt 紅黑樹 特別快 || 非常難寫  

以上操作支援插入刪除O(NlogN)

splay 特別慢。。≈O(sqrt(N))

不太好寫,功能強大


 

可持久化Treap

平衡樹一定是二叉樹

左兒子裡面的元素一定比他小

右兒子一定比當前節點大

中序遍歷一定排好序

每次遞迴的查詢

小——》左

大——》右

弊端:深度可能會非常深-->代價非常大

 


 

Treap=Tree+heap

 

treap:存兩個值[key,val]

val:每次插入的值,滿足平衡樹的性質

key:滿足堆的性質,直接rand,深度一定是logN級別的

 

merge(p1,p2):把以p1為根的Treap和以P2為根的Treap合併成一個Treap,p1的最大值應該<=P2的最小值

split(p,k):把以p為根的Treap拆成兩個Treap,一個有k個數,另一個有n-k個數,k為前k小

插入:先把樹分為x,y兩部分,然後把新的節點a看做是一棵樹,先與x合併,合併完之後將合併的整體與y合併

刪除:

 

 

merge實現

先找key最大的,比較p1,p2

  • 若p1大

p1作為根,p2一定在p1的右邊,

p1.L=p1.L

p1.r=merge(p2,p1.r)

  • 若p2

p2.r=p2.r

p2.L=merge(p2.L,p1)

merge返回的是根節點

 

split實現

size:子樹有多少個節點

當k<=p.L.size—>split(p.L,k)—>設p1為有用的子樹,那麼直接merge(p2,p.r)就好,把p2作為p的左孩子

當k==p.L.size+1 返回p.L+p,p.r

當k>p.L.size+1—>split(p.r,k-p.L.size-1)—>設p2為有用的子樹,直接merge(p,p1),把p1作為p的右孩子

 

相關文章