• 二叉搜索树(BST)模版


      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 const int MAXN=1024;
      4 struct node{
      5     int val;  // val:该节点储存的数值 
      6     int lch, rch; // lch: 左子树根节点编号,rch:右子树根节点编号
      7     int cnt; //该节点储存的数出现的次数(由于我们这里维护的是可重集)
      8     int sz; //以该节点为根节点的子树的节点数目(即子树大小)
      9 };
     10 node bst[MAXN];
     11 int id=1;
     12 //插入 
     13 void insert(int v, int pos=1)//插入
     14 {
     15     bst[pos].sz++;// 以该节点为根节点的子树大小+1
     16     if(bst[pos].val==0 && bst[pos].lch==0 && bst[pos].rch==0){//空节点 
     17         bst[pos].val=v;
     18         bst[pos].cnt=1;
     19     }
     20     else if(v<bst[pos].val){// 向左搜索
     21         if(bst[pos].lch==0)// 如果应该向左搜,但不存在左节点,则创建一个新节点
     22             bst[pos].lch=++id;
     23         insert(v, bst[pos].lch);
     24     }
     25     else if(v>bst[pos].val){// 向右搜索
     26         if(bst[pos].rch==0)
     27             bst[pos].rch=++id;
     28         insert(v, bst[pos].rch);
     29     }
     30     else//已经存在相同值的点 
     31         bst[pos].cnt++;
     32 } 
     33 //删除
     34 void remove(int v, int pos=1){
     35     bst[pos].sz--;
     36     if(v<bst[pos].val)
     37         remove(v, bst[pos].lch);
     38     else if(v>bst[pos].val)
     39         remove(v, bst[pos].rch);
     40     else
     41         bst[pos].cnt--;
     42 } 
     43 //求排名:因为排名被定义为比某数小的数+1,所以我们直接实现两个函数countl和countg,
     44 //用来求比某数小的数的数量和比某数大的数的数量。(这两个函数后面也会用到)
     45 int countl(int v, int pos=1){// 求比某数小的数的个数
     46     if(v<bst[pos].val)
     47         return bst[pos].lch?countl(v, bst[pos].lch):0;
     48     else if(v>bst[pos].val)
     49         return bst[bst[pos].lch].sz+bst[pos].cnt+bst[pos].rch?countl(v, bst[pos].rch):0;
     50     else
     51         return bst[bst[pos].lch].sz;
     52 }
     53 int countg(int v, int pos=1){// 求比某数大的数的个数
     54     if(v>bst[pos].val)
     55         return bst[pos].rch?countg(v, bst[pos].rch):0;
     56     else if(v<bst[pos].val)
     57         return bst[bst[pos].rch].sz+bst[pos].cnt+bst[pos].lch?countg(v, bst[pos].lch):0;
     58     else
     59         return bst[bst[pos].rch].sz;
     60 }
     61 //查询某值在数列中排名 
     62 int rank(int v){
     63     return countl(v, 1)+1;
     64 }
     65 //求指定排名的数
     66 int kth(int k, int pos=1)// 求指定排名的数
     67 {
     68     if(bst[bst[pos].lch].sz+1>k)// 答案在左,在左子树中找排名为k的数
     69         return kth(k, bst[pos].lch);
     70     else if(bst[bst[pos].lch].sz+bst[pos].cnt<k)// 答案在右,在右子树中找排名为k - size[L[pos]] - N[pos]的数
     71         return kth(k-bst[bst[pos].lch].sz-bst[pos].cnt, bst[pos].rch);
     72     else 
     73         return bst[pos].val;
     74 }
     75 //注意,假如某个数的排名为2,且它出现了3次,那么这个函数传入2、3、4都会返回这个数,这也提供了一些方便。
     76 
     77 
     78 //求前驱:根据我们kth函数的性质,直接找到排名比当前数小1的那个数即可。
     79 int pre(int v){
     80     int r=countl(v);
     81     return kth(r);
     82 }
     83 
     84 //求后继:后继的排名则是小于等于当前数的数的数量+1。
     85 int suc(int v){
     86     int r = bst[1].sz - countg(v) + 1;
     87     return kth(r);
     88 } 
     89 int main()
     90 {
     91     //依次插入  10 6 2 5 1 7 4 2 5 9 5
     92     int n;
     93     cin>>n;
     94     for(int i=0; i<n; i++){
     95         int x;
     96         cin>>x;
     97         insert(x);
     98     }
     99     for(int i=1; i<=id; i++)
    100         cout<<i<<":"<<bst[i].val<<" "<<bst[i].lch<<" "<<bst[i].rch<<" "<<bst[i].sz<<" "<<bst[i].cnt<<endl;
    101     cout<<rank(6)<<endl; 
    102     return 0;
    103  } 
  • 相关阅读:
    IO模型
    Java NIO概述
    消息系统避免分布式事务
    JVM调优总结
    设计模式的六大原则
    Java 内存区域与内存溢出
    windows go安装
    ZooKeeper原理及使用
    再谈HashMap
    Html5 播放实时音频流
  • 原文地址:https://www.cnblogs.com/tflsnoi/p/14174361.html
Copyright © 2020-2023  润新知