二叉查找树

二叉查找树是类似于一种堆的数据结构(没有重复元素)

二叉查找有一个性质:中序遍历得到的就是关键码升序排列的序列

这个结构支持很多的操作

  • insert(int val):新增一个关键码为val的节点
  • get(int val):查找关键码为val的节点
  • getnext(int val):查找val的前驱(严格大于val的最小值,可能vall不在树中)
  • getpre(int val):查找val的后继(严格小于val的最大值,可能val不在树中)
  • remove(int val):删除关键码为val的节点
  • getrank(int val):查找val的排名
  • getkth(int k):查找排名为k的val

定义一个二叉查找树

 

struct node{
    ll l,r,val;
}tree[100010];
ll tot,root;
ll newnode(ll val){//新建一个节点
    tree[++tot].val=val;
    return tot;
}void build(){//初始化,建树
    newnode(~0x3f3f3f3f);
    newnode(0x3f3f3f3f);
    root=1;
    tree[1].r=2;
}

 

找关键码为val的节点

//在以tree[p]为根的子树中查找val,主函数调用get(root,val);
ll get(ll p,ll val){//节点编号,关键码
    if(p==0) return 0;
    if(tree[p].val==val) return p;
    else if(tree[p].val>val) return get(tree[p].l,val);
    else return get(tree[p].r,val);
}

新增一个关键码为val的节点

//在以tree[p]为根的子树中查入val,主函数调用insert(root,val);
void insert(ll & p,ll val){
    if(p==0) {
        p=newnode(val);
        return ;
    }
    if(tree[p].val==val) return ;
    else if(tree[p].val>val) insert(tree[p].l,val);
    else insert(tree[p].r,val);
}

查找最小和最大的节点

ll getmin(ll p){
    if(tree[p].l==0) return p;
    return getmin(tree[p].l);
}ll getmax(ll p){
    if(tree[p].r==0) return p;
    return getmax(tree[p].r);
}

查找后继节点

ll getnext(ll val){
    ll p=root,ans=2;
    while(p!=0){
        if(tree[p].val==val){
            if(tree[p].r!=0){
                p=tree[p].r;
                while(tree[p].l!=0) p=tree[p].l;
                return 0;
            }break;
        }if(tree[p].val>val&&tree[p].val<tree[ans].val) ans=p;
        if(tree[p].val>val) p=tree[p].l;
        else p=tree[p].r;
    }return ans;
}

删除节点

void remove(ll & p,ll val){
    if(p==0) return ;
    if(val==tree[p].val){
        if(tree[p].l==0) p=tree[p].r;
        else if(tree[p].r==0) p=tree[p].l;
        else{
            ll next=tree[p].r;
            while(tree[next].l>0) next=tree[next].l;
            remove(tree[p].r,tree[next].val);
            tree[next].l=tree[p].l;
            tree[next].r=tree[p].r;
            p=next;
        }return ;
    }if(val<tree[p].val) remove(tree[p].l,val);
    else remove(tree[p].r,val);
}

 

posted @ 2024-01-23 09:30  努力吧少年^-^  阅读(22)  评论(0)    收藏  举报