splay是乙個實用而且靈活性很強的平衡樹
效率上也比較客觀,但是一定要一次性寫對
debug可能不是那麼容易
splay作為平衡樹,它的平衡方式就是旋轉
暴力旋轉,赤裸裸的旋轉,各種旋轉
就是依靠玄學的旋轉來保證自己的複雜度
不廢話,上主題
struct node //不寫建構函式一時爽,一直不寫一直爽~~~
bool isr() //當前點是否為父親右孩子,旋轉的時候用,方便
int rk() //當前的排名
void upd() //維護資訊
}pool[maxn], *tail, *root, *st[maxn]; //記憶體池與**池,還有根節點
其實這個就是第一節說的旋轉
rot(x)代表把x轉到它父親的位置上去
這也是splay維護平衡的基礎
下面是重點了!!
把x轉到它父親y上
以下**中字母對應,其中那個r是**中的w(因為為中間量,要特殊對待)
void rot(node *x)
以上部分一定要理解透徹!!!這個操作使基於rotate的
splay(x),作用是把x轉到根節點的位置上
顯然要轉好多次的qwq
因為一些玄學的東西(霧
平衡樹中,每次用到誰轉誰(反正不影響性質,說白了貌似還是瞎轉)
這樣玄學的操作可以使splay平衡
void splay(node *x)
}
上面if那一行是啥意思呢?
我們要考慮一條鏈的情況
這種情況我們要先轉父親,再**己
否則直接**己就行
至此,基本操作已經結束qwq
這個是真的暴力插。。。。。。
void ins(int val)
//跳到了空節點上,那麼申請新節點
o = new(top? st[top--] : tail++) node(fa, val, 1);
fa->ch[val > fa->val] = o;
//玄學操作,轉上去
splay(o);
}
這個有點。。鬼畜
一般來說,(我所知道的)有兩種刪除方式,某崔性男子說可以merge(霧
第一種找到要刪節點的前驅和後繼
前驅轉到根,後繼轉到根的右孩子
r的左子樹一定是我們要刪的,直接刪就行了(父子不互認,其他變數清空)
第二種需要兩個函式(好像有點麻煩吧qwq)
node *lst()
返回根的前驅
下面的是真正的刪除
首先把要刪的節點轉到根並記錄一下
找到根的前驅
把根的前驅轉到根
那麼一定是這種情況
原根,也就是要刪的點,一定是沒有左孩子的!!!!
所以類似於鍊錶的操作,把該刪的刪掉
inline void del(int x)
暴力找int rnk(int val)
return splay(lst), rank + 1;
}
其實跟上面差不多int kth(int k)
return splay(o), o->val;
}
這兩個為什麼一塊寫?
因為他們幾乎一樣
int pre(int val)
return lst->val;
}int nxt(int val)
return lst->val;
}
至此,splay完
其實只要理解了,並不是想象那麼難的
放一下完整**
#include#define ll long long
ll in()
const int maxn = 1e5 + 100;
struct splay
bool isr()
int rk()
void upd()
}pool[maxn], *tail, *root, *st[maxn];
int top;
void rot(node *x)
void splay(node *o)
}node *merge(node *x, node *y, node *fa)
public:
splay()
int rnk(int val)
return splay(lst), rank + 1;
}int kth(int k)
return splay(o), o->val;
}void ins(int val)
o = new(top? st[top--] : tail++) node(fa, val, 1);
fa->ch[val > fa->val] = o;
splay(o);
}void del(int val)
if(!o) return;
splay(o);
root = merge(o->ch[0], o->ch[1], null);
st[++top] = o;
}int pre(int val)
return lst->val;
}int nxt(int val)
return lst->val;
}}v;int main()
return 0;
}
學習筆記 普通平衡樹Splay
哈哈哈哈哈哈哈終於會打 splay 啦 現在我來發一下 splay 的講解吧 小蒟蒻由於碼風與他人不同,所以自己找了上百篇碼風詭異的 splay 合成的,感謝 zcysky 的 與我碼風相近,讓我看懂了 首先,splay 其實就是把一棵二叉搜尋樹變成一棵深度不會超過 logn 的二叉搜尋樹,它在不斷...
平衡樹學習筆記(1) splay
3.一些廢話 4.不知道是不是廢話的話 中考加油!splay原名伸展樹 splay tree 也叫 樹,是一種二叉排序樹,它能在o log n 內完成插入 查詢和刪除操作。它由丹尼爾 斯立特 daniel sleator 和羅伯特 恩卓 塔揚 robert endre tarjan 在1985年發明...
平衡樹之splay
在每次查詢之後對樹進行重構 把被查詢的條目搬移到 離樹根近一些的地方。伸展樹應運而生。伸展樹是一種自調整形式的二叉查詢樹,它會 沿著從某個節點到樹根之間的路徑 通過一系列的旋轉把這個節點搬移到樹根去。大家只需要記住,每次進行插入 查詢的時候,都要把插入 查詢的元素通過旋轉變到根的位置,splay 的...