码迷,mamicode.com
首页 > 其他好文 > 详细

BST入门

时间:2020-03-18 11:58:41      阅读:59      评论:0      收藏:0      [点我收藏+]

标签:line   root   位置   scanf   bst   入门   lse   相对   space   

BST 即 搜索二叉树,它的性质,简而言之,就是对于每一个结点,他的左节点严格小于它,它的右节点严格大于他,满足这样性质的数就是搜索二叉树,它支持求x数的排名(在这里规定,有多个相同的数时,求他的最大排名),求排名x的数,求x数的前驱和后继,加入结点,删除结点

那么,要满足上面的性质,如果有多个相同的数该如何处理呢?我们的处理办法是增加一个变量cnt,记录这样的数出现的次数即可

代码实现如下:

#include<iostream>
#include<cstdio>
using namespace std;
struct node {
    int ls,rs,cnt,v,size;
    node(int left,int right,int size,int value)
        :(ls)left,(rs)right,size(size),v(value),cnt(1){}
    node(){}
}tree[100001];
int num;
inline void update(int root) {
    tree[root].size = tree[tree[root].ls].size+tree[tree[root].rs].size+tree[root].cnt;
}
void Insert(int x, int root) {
    if(x==tree[root].v)
        tree[root].cnt++;
        return ;
    else if(x<tree[root].v) {
        if(tree[root].ls) Insert(x,tree[root].ls);
        else tree[tree[root].ls  = ++num ]    = node(0,0,1,x);
    }
    else if(x>tree[root].v) {
        if(tree[root].rs) Insert(x,tree[root].rs);
        else tree[tree[root].rs = ++num] = node(0,0,1,x)    
    }
    return ;
    update(root);
}
int rank_value(int x, int root) {
    if(x<=tree[tree[root].ls].size)
        return rank_value(x,tree[root].ls);
    else if(x<=tree[tree[root].ls].size+tree[root].cnt)
        return tree[root].v;
    else return rank_value(x-tree[tree[root].ls].size-tree[root].cnt,tree[root].rs);
}//查询排名x的数
int value_rank(int x, int root) {
    if(root) {
        if(tree[root].v<x)
            return value_rank(x,tree[root].ls)
        else if(tree[root].v>x) 
            return value_rank(x,tree[root].rs)+tree[root].cnt+tree[tree[root].ls].size;
        else if(tree[root].v == x) 
            return tree[tree[root].ls].size+tree[root].cnt;
    }//对于一个不存在的数,也可以查询他在序列中的相对位置 
    return 1;
}//查询数x的排名
int pre(int x, int root, int ans ) {
    if(x<=tree[root].v) {
        if(!tree[root].ls) return ans;
        else return pre(x,tree[root].ls,ans); 
    }
    if(x>tree[root].v) {
        if(!tree[root].rs) return ans;
        else return pre(x,tree[root].rs,tree[root].v) 
    }
     
}//查询数x的前驱 
int main() {
        int n,op,x,root;
    scanf("%d",&n);
    tree[root = ++num] = node(0,0,1,2147483647);
    while(n--) {
        scanf("%d%d",&op,&x);
        if(op==1) {
            cout<<value_rank(x,root)<<endl;//x 的 rank 
        } else if(op==2) {
            cout<<rank_value(x,root)<<endl;//rank为x的数
        } else if(op==3) {
            cout<<pre(x,root,2147483647)<<endl;
        } else if(op==4) {
            cout<<rank_value(value_rank(x+1,root),root)<<endl;//可以替代后继函数 
        } else Insert(x,root);
    }
    return 0;
} 

 

BST入门

标签:line   root   位置   scanf   bst   入门   lse   相对   space   

原文地址:https://www.cnblogs.com/delta-cnc/p/12516027.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!