就是比二叉查找树多了几个点

1.左旋右旋的时候记得更新子树节点个数,外面如果不旋转要直接++cnt

2.之前遇到相等的值向右插的方法能够保证查找“值为x”的最小节点下标时,搜到的第一个点下标最小。然而,在←→旋之后这一性质可能被破坏(比如{data=3,r=1},{data=1,r=4},{data=1,r=3}

  1 #include<stdio.h>
  2 #include<cstdlib>
  3 #include<ctime>
  4 #define lch ch[0]
  5 #define rch ch[1]
  6 using namespace std;
  7 const int maxN = 600002;
  8 int n;
  9 int brand()
 10 {
 11     int a = rand(), b = rand();
 12     return ((a&0x7FFF) << 15) | (b&0x7FFF);
 13 }
 14 struct node
 15 {
 16     int data, cnt, r;
 17     node* ch[2];
 18     node()
 19     {data = 0; cnt = 1; r = brand(); ch[0] = ch[1] = 0;}
 20 };
 21 typedef node* pnode;
 22 pnode root = 0;
 23 int num(pnode t)
 24 {return t ? t->cnt : 0;}
 25 void maintain(pnode &t, int d)
 26 {
 27     pnode p = t->ch[d];
 28     t->ch[d] = p->ch[d^1];
 29     p->ch[d^1] = t;
 30     t->cnt = num(t->lch) + num(t->rch) + 1;
 31     p->cnt = num(p->lch) + num(p->rch) + 1;
 32     t = p;
 33 }
 34 void addn(pnode &t, int x)
 35 {
 36     if(!t)
 37     {
 38         t = new node;
 39         t->data = x;
 40         return;
 41     }
 42     if(t->data > x)
 43     {
 44         addn(t->lch,x);
 45         if(t->r > t->lch->r)
 46             maintain(t,0);
 47         else
 48             ++t->cnt;
 49     }
 50     else
 51     {
 52         addn(t->rch,x);
 53         if(t->r > t->rch->r)
 54             maintain(t,1);
 55         else
 56             ++t->cnt;
 57     }
 58 }
 59 int require(pnode t, int x)
 60 {
 61     if(!t)
 62         return -2;
 63     if(t->data > x)
 64         return require(t->lch,x);
 65     if(t->data == x)
 66     {
 67         int tmp = require(t->lch,x);
 68         return tmp == -2 ? num(t->lch) : tmp;
 69     }
 70     int tmp = require(t->rch,x);
 71     return tmp == -2 ? -2 : (tmp + num(t->lch) + 1);
 72 }
 73 int ask(pnode t, int x)
 74 {
 75     if(!t || x < 1 || x > num(t))
 76         return -1;
 77     if(x < num(t->lch) + 1)
 78         return ask(t->lch,x);
 79     if(x > num(t->lch) + 1)
 80         return ask(t->rch,x-num(t->lch)-1);
 81     return t->data;
 82 }
 83 int main()
 84 {
 85     srand(time(0));
 86     //freopen("ipt.txt","r",stdin);
 87     //freopen("opt2.txt","w",stdout); 
 88     char opt; int inp;
 89     scanf("%d",&n);
 90     getchar();
 91     while(n--)
 92     {
 93         scanf("%c",&opt); getchar(); scanf("%d",&inp); getchar();
 94         //printf("opt=%c  inp=%d\n",opt,inp);
 95         if(opt == 'I')
 96             addn(root,inp);
 97         else if(opt == 'R')
 98             printf("%d\n",require(root,inp)+1);
 99         else
100             printf("%d\n",ask(root,inp));
101     }
102     return 0;
103 } 

(显然未完待续。。。)

posted on 2019-05-16 23:37  Duyy  阅读(127)  评论(0编辑  收藏  举报