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)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 "); 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: "); 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: "); 96 add(r, v, true); t[p].r = r; //t[p].r本身须被改变 97 if(t[r].h-t[l].h == 2){ 98 //printf("r: "); 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 ", root); 112 print(p); 113 printf(" "); 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 ", query(root, t[root].c+1-k)); 144 145 } 146 } 147 148 return 0; 149 }