zoukankan      html  css  js  c++  java
  • BST入门

    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;
    } 
  • 相关阅读:
    FarPoint FpSpread控件的使用收藏
    在Oracle中使用Guid
    oracle 语句的妙用例子
    让服务器iis支持.apk文件下载的设置方法
    oracle 自动生存清库脚本
    winform 消息通讯组件实习
    在css中使用边框做三角形
    JavaScript闭包和ajax
    JavaScript面向对象
    正则表达式
  • 原文地址:https://www.cnblogs.com/delta-cnc/p/12516027.html
Copyright © 2011-2022 走看看