平衡樹 模板

2021-10-25 10:23:47 字數 2348 閱讀 6155

例題p3369 【模板】普通平衡樹

概念: 平衡樹是二叉搜尋樹和堆合併構成的資料結構,它是一 棵空樹或它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹。

性質:對於每乙個節點,滿足它大於左兒子裡的每乙個節點,小於右兒子的每乙個節點,即樹的中序遍歷為有序序列

對於乙個平衡樹,它可以支援的操作有

1:插入乙個值

2:刪除乙個值

3:查詢乙個 x

xx 的排名

4:查詢排名為 x

xx 的值

5:查詢嚴格小於 x

xx 的最大值

6:查詢嚴格大於 x

xx 的最小值

時間複雜度:不論哪一種操作,所花的時間都和樹的高度成正比。因此,如果共有n個元素,

那麼平均每次操作需要 o(l

ogn)

o(logn)

o(logn

) 的時間,所以我們要盡量讓這棵樹隨機.

那麼對於每乙個節點,我們可以這樣定義

struct tr

tree[n]

;

l,r

l,rl,

r 為樹的左右兒子的編號,siz

sizsi

z 為這棵子樹的節點個數,val

valva

l 為乙個隨機值,key

keyke

y 是維護的值, cnt

cntcn

t 為當前值的個數

通過v al

,key

val,key

val,ke

y,我們可以讓這棵樹足夠隨機,只需要這棵樹滿足大根堆的性質,val

valva

l 大的在上面.

首先是pushup,這裡pushup的作用主要是更新子樹大小

void

pushup

(ll p)

新建乙個節點

int

get_node

(int key)

在新建節點的時候,因為 val

valva

l 是隨機的,所以可能不滿足大根對的性質,所以就需要乙個操做交換兩個節點,也就是左旋和右旋

可以看出,在經過左旋或右旋後,樹的中序遍歷不變

通過可以寫出**

void

zig(

int&p)

//這裡需要加引用,因為左旋或右旋過後根節點會變

void

zag(

int&p)

對於插入操作,如果當前值存在,那麼就先找到當前值然後cnt++,如果不存在就新建節點,具體看**

void

insert

(int

&p,int key)

else

pushup

(p);

}

對於刪除操作,其實和插入差不多,因為在中間刪除節點很麻煩,所以就先將該接節點移到葉節點

void

del(

int&p,

int key)

else

}else

//如果是葉節點就直接刪除

p =0;

}else

if(key

.key)

del(tree[p]

.l, key)

;//往左子樹找

else

del(tree[p]

.r, key)

;//往右子樹找

pushup

(p);

}

通過數值查詢排名,具體看**

int

getrank

(int p,

int key)

通過排名查詢數值

int

getkey

(int p,

int rank)

查詢小於x的最大值和大於x的最小值

int

getpre

(int p,

int key)

intgetnet

(int p,

int key)

平衡樹模板 Treap

演算法標籤 treap 種下第一棵平衡樹 這是一道模板題。如果覺得這個題水的可以做一下4544壓行,是千古神犇花爸爸出的神犇題。您需要寫一種資料結構 可參考題目標題,但是這句話其實並沒有什麼用233 來維護一些數,其中需要提供以下操作 1.插入x數 2.刪除x數 若有多個相同的數,因只刪除乙個 3....

模板 文藝平衡樹

由於中序遍歷不會因為旋轉改變,平衡樹可以作為區間樹使用。翻轉用打標記的方法,splay x,y 代表把x接到以y為根的子樹下面。include include using namespace std const int maxn 100005 int n,m int val maxn siz max...

(模板)Splay 平衡樹

不會講解,直接上板子,按照洛谷p3369的要求 include include include using namespace std const int maxn 1000000 int ch maxn 2 f maxn size maxn cnt maxn key maxn int nodecn...