二叉查找树(平衡树的根源)

#include<bits/stdc++.h>
using namespace std;
const int N=100010;
int root,tot;
int sz[N],val[N],ch[N][2],fa[N];
void pushup(int x){
	if(!x)return;
    sz[x]=1;
	if(ch[x][0])sz[x]+=sz[ch[x][0]],fa[ch[x][0]]=x;
    if(ch[x][1])sz[x]+=sz[ch[x][1]],fa[ch[x][1]]=x;
}
void insert(int &rt,int v){
    if(!rt){
        rt=++tot;
        val[rt]=v;
        ch[rt][0]=ch[rt][1]=0;
        sz[rt]=1;
        return;
	}
	if(v>val[rt])insert(ch[rt][1],v);
	else insert(ch[rt][0],v);
	pushup(rt);
}
int erased;
void erasesuc(int&rt){
    if(ch[rt][0]){
        erasesuc(ch[rt][0]);
	}else{
		erased=val[rt];
	    rt=ch[rt][1];
	    return;
	}
	pushup(rt);
}
void erase(int&rt,int v){
    if(val[rt]==v){
        if(!ch[rt][0]||!ch[rt][1]){
		    rt=ch[rt][0]+ch[rt][1];
		}else{
			erasesuc(ch[rt][1]);
			val[rt]=erased;
		}
		pushup(rt);
		return;
	}
	if(v<val[rt])erase(ch[rt][0],v);
	else erase(ch[rt][1],v);
	pushup(rt);
}
int rnk(int rt,int x){
	if(!rt)return 0;
    if(x<=val[rt])return rnk(ch[rt][0],x);
    else return sz[ch[rt][0]]+1+rnk(ch[rt][1],x);
}
int kth(int rt,int x){
    if(x<=sz[ch[rt][0]])return kth(ch[rt][0],x);
    else if(x==sz[ch[rt][0]]+1)return val[rt];
    else return kth(ch[rt][1],x-sz[ch[rt][0]]-1);
}
int pre(int x){
    return kth(root,rnk(root,x));
}
int suc(int x){
    return kth(root,rnk(root,x+1)+1);
}
void print(int rt){
    if(!rt)return;
    print(ch[rt][0]);
    printf("%d ",val[rt]);
    print(ch[rt][1]);
//    pushup(rt);
}
int main(){
	freopen("1.in","r",stdin);
	int n;
    cin>>n;
    while(n--){
        int op,x;
        scanf("%d%d",&op,&x);
        if(op==1){
            insert(root,x);
		}else if(op==2){
		    erase(root,x);
		}else if(op==3){
		    printf("%d\n",rnk(root,x)+1);
		}else if(op==4){
			printf("%d\n",kth(root,x));
		}else if(op==5){
			printf("%d\n",pre(x));
		}else {
			printf("%d\n",suc(x));
		}
//		print(root),puts("");
	}
}
posted @ 2019-07-22 21:04  整理者  阅读(185)  评论(0编辑  收藏  举报