AVL树入门

AVL树,平衡树的一种,插入,删除,询问均为O(lgn)。

这些天学了下它的实现,(删除貌似很麻烦,还不会。。)

它的插入同查找树,之后靠旋转来维持平衡。

旋转分4种情形:LL, LR, RL, RR;

LL 可以 由一次右单旋平衡,与之对称的,RR 可以 由一次左单旋平衡。

LR 则须 由一次左单旋,先变为LL,再由一次右单旋平衡 。(即一次左右双旋

RL 与之对称的,一次右左双旋

详见:

http://blog.csdn.net/gabriel1026/article/details/6311339

 

应用一:动态查询 整颗树中第k大数。

hdu 4006: http://acm.hdu.edu.cn/showproblem.php?pid=4006

题意不含删除操作~, O(qlgn)

 

  1 #include<map>
  2 #include<set>
  3 #include<list>
  4 #include<cmath>
  5 #include<ctime>
  6 #include<queue>
  7 #include<stack>
  8 #include<cctype>
  9 #include<cstdio>
 10 #include<string>
 11 #include<vector>
 12 #include<cstdlib>
 13 #include<cstring>
 14 #include<iostream>
 15 #include<algorithm>
 16 #define MAXN 1000005
 17 #define INF 0x3f3f3f3f
 18 #define LL long long
 19 #define Test() cout<<"Test"<<endl;
 20 #define Debug(a) cout<<#a<<" = "<<a<<endl;
 21 #define Debug2(a,b) cout<<#a<<" = "<<a<<" , "<<#b<<" = "<<b<<endl;
 22 using namespace std;
 23 
 24 struct node{
 25     int v, h;    // v:value, h: hight
 26     int l, r;    // 2 children
 27     int c;        // 树的size, 即节点数
 28 };
 29 typedef struct node AVL;    //inscreasing order
 30 AVL t[MAXN];
 31 int root, ie;
 32 
 33 void init(){
 34     root = 0, ie = 1;
 35     t[0].h = -1;    //以t[0]为空树。
 36     t[0].c = 0;
 37 }
 38 
 39 void pushUp(int p){
 40     int l=t[p].l, r=t[p].r;
 41     t[p].h = max(t[l].h, t[r].h)+1;
 42     t[p].c = t[l].c + t[r].c + 1;
 43 }
 44 
 45 //L(), R() 均为单旋, 以 q 为轴,将p向下旋
 46 void L(int &p){        // p在q的左边, 称之为左单旋
 47     int q=t[p].r, tmp;
 48     t[p].r = t[q].l;
 49     t[q].l = p;
 50     tmp=p, p=q, q=tmp;    //由于此时q为根, swap(p, q)    
 51     pushUp(q);            //先q后p
 52     pushUp(p);
 53 }
 54 
 55 void R(int &p){        // p在q的右边, 称之为右单旋
 56     int q=t[p].l, tmp;
 57     t[p].l = t[q].r;
 58     t[q].r = p;
 59     tmp=p, p=q, q=tmp;        
 60     pushUp(q);    
 61     pushUp(p);
 62 }
 63 /*
 64 void print(int p){
 65     printf(",(");
 66     if(p){
 67         printf("%d", t[p].v);
 68         print(t[p].l);        
 69         print(t[p].r);
 70     }
 71     printf("),");
 72 }
 73 */
 74 void add(int &p, int v, bool f){    //对于重复元素, f=0: 插在left
 75     int l=t[p].l, r=t[p].r;
 76     if(!p){
 77         //printf("added\n");
 78         t[ie].v=v, t[ie].c=1;
 79         t[ie].h = t[ie].l = t[ie].r=0;
 80         p = ie++;
 81         //return ;
 82     }
 83     else if(v<t[p].v || (v==t[p].v && f==0)){
 84         //printf("left:\n");
 85         add(l, v, false); t[p].l = l;    //t[p].l本身须被改变
 86         if(t[l].h-t[r].h == 2){
 87             if(v <= t[l].v)
 88                 R(p);
 89             else{
 90                 L(l); t[p].l=l;
 91                 R(p);
 92             }
 93         }
 94     }else if(v>t[p].v || (v==t[p].v && f)){
 95         //printf("right:\n");
 96         add(r, v, true); t[p].r = r;    //t[p].r本身须被改变    
 97         if(t[r].h-t[l].h == 2){
 98             //printf("r:\n");
 99             if(v >= t[r].v)
100                 L(p);
101             else{
102                 R(r); t[p].r=r;
103                 L(p);
104             } 
105         }
106     }else{
107         ;    //允许重复值
108     }
109     pushUp(p);
110     /*
111     printf("p : %d\n", root);
112     print(p);
113     printf("\n");
114     */
115 }
116 
117 //void remove(){}
118 
119 int query(int p, int k){
120     int l=t[p].l, r=t[p].r; 
121     if(k == t[l].c+1)
122         return t[p].v;
123     else if(k > t[l].c+1)
124         return query(r, k-(t[l].c+1));
125     else
126         return query(l, k);
127 }
128 
129 //hdu 4006
130 int main()
131 {
132     int m, k, x;
133     while(~scanf("%d%d", &m, &k)){
134         init();
135         while(m--){
136             char s[5];
137             scanf("%s", s);
138             if(s[0] == 'I'){
139                 cin >> x;
140                 add(root, x, false);
141             }
142             else
143                 printf("%d\n", query(root, t[root].c+1-k));
144             
145         }
146     }
147 
148     return 0;
149 }
View Code

 

 

 

posted on 2013-12-04 22:13  KimKyeYu  阅读(317)  评论(0编辑  收藏  举报

导航