入門平衡樹 Treap

2022-06-02 06:42:07 字數 2886 閱讀 8302

前言:

前置知識:

初識\(bst\):

2:\(bst\)性質

舉個拓展的例子,笛卡爾樹既滿足堆性質,又滿足\(bst\)性質。

那麼我們接下來介紹的二叉搜尋樹就是一棵滿足\(bst\)性質的二叉樹,可以結合此圖加深理解。

\(bst\)的建立:

const int inf = 0x3f3f3f3f;

int tot, root, n;

struct treap //入門級平衡樹

a[maxn];

int new(int val)

void build()

\(bst\)的檢索:

當\(val\)小於當前節點的關鍵碼

當\(val\)大於當前節點的關鍵碼

int get(int &p, int val)

if(val == a[p].val) return p;

return val < a[p].val ? get(a[p].l, val) : get(a[p].r, val);

}

\(bst\)的插入:
void ins(int &p, int val)

if(val == a[p].val) return;

if(val < a[p].val) ins(a[p].l, val);

else ins(a[p].r, val);

}

\(bst\)求前驅/後繼:
int getnext(int val)

break;

}if(a[p].val >val && a[p].val < a[ans].val) ans = p;

p = val < a[p].val ? a[p].l : a[p].r;

}return a[ans].val;

}

\(bst\)的節點刪除:

此時我們直接刪除節點\(next\)(刪除之前要記錄一下),再用\(next\)的右子樹代替節點\(next\)的位置,再刪除\(p\),再用記錄下來的\(next\)代替\(p\)的位置。

其他:\(bst\)複雜度分析

\(bst\)時間複雜度分析:

其中入門級別的平衡樹是\(treap\),較為常用的是\(splay\)。本著入門的精神,接下來我們來看看\(treap\)。

旋轉操作:

什麼樣旋轉是合理的?

acwing255: 普通平衡樹

洛谷3369: 普通平衡樹

#includeusing namespace std;

typedef long long ll;

const int maxn = 1e5 + 10;

const int inf = 0x3f3f3f3f;

int tot, root, n;

struct treap

a[maxn];

//新建乙個節點

int new(int val)

void update(int p)

//初始建立treap 其中有兩個特殊節點

void build()

int getrankbyval(int p, int val)

//查詢排名為rk的數

int getvalbyrank(int p, int rk)

void zig(int &p) //右旋操作

void zag(int &p) //左旋操作 同理與右旋

//插入和刪除操作 一般會涉及到旋轉

//所以這時候採用遞迴寫法 以便於更新節點資訊

void ins(int &p, int val)

if(val == a[p].val)

if(val < a[p].val)

else

update(p);

}//找到需要刪除的節點並將其下旋至葉子節點後刪除

//減少維護節點資訊等複雜問題

void del(int &p, int val)

if(a[p].l || a[p].r)//不是葉子節點 向下旋轉

//右旋 後進入右子樹

else

update(p);//例行更新父節點資訊

}else p = 0; //是葉子節點 直接刪除

return;

}val < a[p].val ? del(a[p].l, val) : del(a[p].r, val);

update(p);

}int getpre(int val)

break; //此時的ans為答案

}//就算找不到val 前驅也被ans經過了

if(a[p].val < val && a[p].val > a[ans].val) ans = p;

p = val < a[p].val ? a[p].l : a[p].r;

}return a[ans].val;

}int getnext(int val)

break;

}if(a[p].val >val && a[p].val < a[ans].val) ans = p;

p = val < a[p].val ? a[p].l : a[p].r;

}return a[ans].val;

}int main()

if(op == 2)

if(op == 3)

if(op == 4)

if(op == 5)

if(op == 6)

}return 0;

}

平衡樹之Treap

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

Treap 普通平衡樹

最近學習了treap,找了道題目做做 全抄hz.因為普通的二叉樹,會退化成鏈 所以你把讀入打亂順序再構造二叉樹,就明顯卡不掉 平平均深度logn treap就是這樣的 在插入乙個數時,我們搞乙個rnd,賦值隨機 然後如果當前的這個節點rnd小於其父節點,那麼就把他轉到父節點的位置 這樣好比是給這個節...

平衡樹模板 Treap

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