博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[普通平衡树splay]【学习笔记】
阅读量:5878 次
发布时间:2019-06-19

本文共 4014 字,大约阅读时间需要 13 分钟。

参考:

http://blog.csdn.net/clove_unique/article/details/50630280

gty课件

找一个好的风格太难了,自己习惯用struct,就强行用struct写了一下数组版的,同时加了些宏简化代码

都是迭代写法

splay要维护fa指向父亲

rotate是把x转到fa,要更新f和x

splay是把x转到tar的孩子,x成为root就是tar=0,注意更新root

ins考虑空树,考虑已经存在,插入新节点的话要保留last到最后处理父亲,然后做splay

(递归写法的传引用已经解决了设置祖先的问题)

del

先找要删除的,splay到根

1.多个直接--

2.空树直接root=0

3.只有一个儿子,令独生子变成根,删去该点。

4.左右儿子都有。找到左子树中权值最大的点,将其 splay 到左儿子的位置。然后将 整棵右子树挂在左儿子的右边。删除节点。 

其他操作差不多了

 

ps:比treap慢了一倍

 

////  main.cpp//  splay////  Created by Candy on 27/11/2016.//  Copyright © 2016 Candy. All rights reserved.//#include 
#include
#include
#include
#include
using namespace std;#define pa t[x].fa#define lc t[x].ch[0]#define rc t[x].ch[1]const int N=2e5+5;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}struct node{ int fa,ch[2],v,w,size;}t[N];int cnt,root;inline int wh(int x){
return t[pa].ch[1]==x;}inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}inline void rotate(int x){
//x-->pa int f=t[x].fa,g=t[f].fa,c=wh(x); if(g) t[g].ch[wh(f)]=x; t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f; t[x].ch[c^1]=f;t[f].fa=x; t[x].fa=g; update(f);update(x);}inline void splay(int x,int tar){
//x-->x.fa==tar for(;t[x].fa!=tar;rotate(x)) if(t[pa].fa!=tar) rotate(wh(x)==wh(pa)?pa:x); if(tar==0) root=x;}inline int nw(int v){ cnt++; t[cnt].v=v;t[cnt].ch[0]=t[cnt].ch[1]=t[cnt].fa=0; t[cnt].w=t[cnt].size=1; return cnt;}inline void ins(int v){ if(root==0){root=nw(v);return;}//empty tree int x=root,last=0; while(x!=0){ if(t[x].v==v){t[x].w++;t[x].size++;splay(x,0);return;} last=x; if(v
1) {t[x].w--,t[x].size--;return;} if(lc==0&&rc==0) root=0; else if(rc==0) t[lc].fa=0,root=lc; else if(lc==0) t[rc].fa=0,root=rc; else{ int tmp=t[root].ch[0]; while(t[tmp].ch[1]) tmp=t[tmp].ch[1]; splay(tmp,x); t[tmp].ch[1]=rc;t[rc].fa=tmp; t[tmp].fa=0; root=tmp; update(root); }}inline int rnk(int v){ int x=root,ls=0; while(x!=0){ if(t[x].v==v){ int ans=ls+t[lc].size+1; splay(x,0); return ans; } if(v
View Code

 

[2016-11-30]

复习了一遍

注意:

find和ins操作要splay,有的地方直接return的话忘记splay了

#include 
#include
#include
#include
#include
using namespace std;#define pa t[x].fa#define lc t[x].ch[0]#define rc t[x].ch[1]const int N=2e5+5;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}struct node{ int fa,ch[2],w,size,v;}t[N];int cnt,root;inline void update(int x){t[x].size=t[lc].size+t[rc].size+t[x].w;}inline int wh(int x){
return t[pa].ch[1]==x;}inline void rotate(int x){ int f=t[x].fa,g=t[f].fa,c=wh(x); if(g) t[g].ch[wh(f)]=x;t[x].fa=g; t[f].ch[c]=t[x].ch[c^1];t[t[f].ch[c]].fa=f; t[x].ch[c^1]=f;t[f].fa=x; update(f);update(x);}inline void splay(int x,int tar){ for(;t[x].fa!=tar;rotate(x)) if(t[pa].fa!=tar) rotate(wh(pa)==wh(x)?pa:x); if(tar==0) root=x;}inline int nw(int v){ cnt++; t[cnt].ch[0]=t[cnt].ch[1]=t[cnt].fa=0; t[cnt].w=t[cnt].size=1;t[cnt].v=v; return cnt;}void ins(int v){ if(root==0){root=nw(v);return;} int x=root,last=0; while(x){ if(t[x].v==v){t[x].w++;t[x].size++;splay(x,0);return;} last=x; if(v
1){t[x].w--;t[x].size--;return;} if(lc==0&&rc==0) root=0; else if(rc==0) t[lc].fa=0,root=lc; else if(lc==0) t[rc].fa=0,root=rc; else{ int _=lc; while(t[_].ch[1]) _=t[_].ch[1]; splay(_,x); t[_].ch[1]=rc;t[rc].fa=_; t[_].fa=0;root=_; update(root); }}int rnk(int v){ int x=root,ls=0; while(x){ if(t[x].v==v){ int ans=ls+t[lc].size+1; splay(x,0); return ans; } if(v
t[x].v) ans=x,x=rc; else x=lc; } return ans;}int suf(int v){ int x=root,ans=0; while(x){ if(v

 

你可能感兴趣的文章
Linux的链接文件-ln命令
查看>>
maven的tomcat插件如何进行debug调试
查看>>
table表头固定
查看>>
截取字符串中两个字符串中的字符串
查看>>
spring xml properties split with comma for list
查看>>
判断点是否在三角形内
查看>>
Android实战简易教程-第二十三枪(基于Baas的用户注冊验证username是否反复功能!)...
查看>>
在odl中怎样实现rpc
查看>>
leetcode 110 Balanced Binary Tree
查看>>
python活用isdigit方法显示系统进程
查看>>
项目开发总结
查看>>
知行合一
查看>>
jmeter插件之jsonpath提取响应结果和做断言
查看>>
发布支持多线程的PowerShell模块 —— MultiThreadTaskRunner
查看>>
Ubuntu ctrl+alt会导致窗口还原的问题
查看>>
第四十期百度技术沙龙笔记整理
查看>>
推荐系统那点事 —— 基于Spark MLlib的特征选择
查看>>
linux 下RTL8723/RTL8188调试记录(命令行)【转】
查看>>
SpringMVC案例1——对User表进行CRUD操作
查看>>
看雪CTF第十四题
查看>>