社区讨论

AVL树求条

学术版参与者 2已保存回复 2

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
2 条
当前快照
1 份
快照标识符
@mhpi303r
此快照首次捕获于
2025/11/08 07:42
3 个月前
此快照最后确认于
2025/11/08 07:42
3 个月前
查看原帖
CPP
#include<iostream>
#include<cmath>
#define int long long
#define inf 0x3f3f3f3f
using namespace std;

const int MAXL=1e6+5;
int tot,rt;
struct node{
	int l,r,v;
    int cnt,sz,bf,h;
}tr[MAXL];

int newnode(int v){
    tr[++tot].v=v;
    tr[tot].cnt=tr[tot].sz=tr[tot].h=1;
    return tot;
}
void recover(int x){
    int l=tr[x].l,r=tr[x].r;
    tr[x].sz=tr[l].sz+tr[r].sz+tr[x].cnt;
    tr[x].h=max(tr[tr[x].l].h,tr[tr[x].r].h)+1;
    tr[x].bf=tr[tr[x].l].h-tr[tr[x].r].h;
}
void build(){
	newnode(-inf),newnode(inf);
	rt=1,tr[1].r=2;
    recover(rt);
}
void rrotate(int &x){
    int y=tr[x].l;
    tr[x].l=tr[y].r;
    tr[y].r=x,x=y;
    recover(tr[x].r);
    recover(x);
}
void lrotate(int &x){
    int y=tr[x].r;
    tr[x].r=tr[y].l;
    tr[y].l=x;
    x=y;
    recover(tr[x].l);
    recover(x);
}
void maintain(int &x){
    recover(x);
    int l=tr[x].l,r=tr[x].r;
    int bf=tr[x].bf;
    if(bf==2){
        if(tr[tr[l].l].h>=tr[tr[r].l].h)rrotate(x);
        else lrotate(l),rrotate(x);
    }
    else if(bf==-2){
        if(tr[tr[l].r].h<=tr[tr[r].r].h)lrotate(x);
        else rrotate(r),lrotate(x);
    }
    recover(x);
}
void insert(int &x,int v){
    if(x==0){
        x=newnode(v);
        return;
    }
    if(v==tr[x].v){
        tr[x].cnt++;
        recover(x);
        return;
    }
    if(tr[x].v>v)insert(tr[x].l,v);
    else insert(tr[x].r,v);
    maintain(x);
}
void remove(int &x,int v){
    if(x==0)return;
    if(v==tr[x].v){
        if(tr[x].cnt>1){
            tr[x].cnt--;
            recover(x);
            return;
        }
        if(tr[x].l&&tr[x].r){
            int nxt=tr[x].r;
            while(tr[nxt].l)nxt=tr[nxt].l;
            tr[x].v=tr[nxt].v;
            remove(tr[x].r,tr[nxt].v);
        }
        else if(tr[x].l)x=tr[x].l;
        else if(tr[x].r)x=tr[x].r;
        else x=0;
    }
    else if(tr[x].v>v)remove(tr[x].l,v);
    else remove(tr[x].r,v);
    maintain(x);
}
int getnext(int v){
	int x=rt,ans=2;
	while(x){
		if(tr[x].v==v){
			if(tr[x].r){
				x=tr[x].r;
				while(tr[x].l)x=tr[x].l;
				return x;
			}
			break;
		}
		if(tr[x].v>v&&tr[x].v<tr[ans].v)ans=x;
		if(tr[x].v>v)x=tr[x].l;
		else x=tr[x].r;
	}
	return ans;
}
int getpre(int v){
	int x=rt,ans=1;
	while(x){
		if(tr[x].v==v){
			if(tr[x].l){
				x=tr[x].l;
				while(tr[x].r)x=tr[x].r;
				return x;
			}
			break;
		}
		if(tr[x].v<v&&tr[x].v>tr[ans].v)ans=x;
		if(tr[x].v>v)x=tr[x].l;
		else x=tr[x].r;
	}
	return ans;
} 
int getrnk(int x,int v){
    if(x==0)return 1;
    if(v==tr[x].v)return tr[tr[x].l].sz+1;
    if(v<tr[x].v)return getrnk(tr[x].l,v);
    return getrnk(tr[x].r,v)+tr[tr[x].l].sz+tr[x].cnt;
}
int getkth(int x,int k){
    if(k>tr[x].sz)return 2;
    if(k<=tr[tr[x].l].sz)return getkth(tr[x].l,k);
    if(k<=tr[tr[x].l].sz+tr[x].cnt)return x;
    return getkth(tr[x].r,k-tr[tr[x].l].sz-tr[x].cnt);
}
蒟蒻没学过AVL,但是后面的四个函数都是从BST粘过来的,应该没错。就是maintain,insert和remove是新写的。有无大佬指出错误?
另外,有没有大佬能给一下自己的AVL插入、删除和维护平衡性三个函数?

回复

2 条回复,欢迎继续交流。

正在加载回复...