1. 程式人生 > 其它 >二叉平衡樹

二叉平衡樹

  1 # include<iostream>
  2 # include<stdio.h>
  3 # include<algorithm>
  4 # include<string>
  5 using namespace std;
  6 /*建樹的過程和二叉樹大差不差*/
7 const int N = 100010, INF = 1e8; 8 9 int n; 10 struct node { 11 int l, r; 12 int key, val; 13 int cnt, size; 14 } tr[N];
15 16 int root, idx; 17 18 void pushup(int p) { 19 tr[p].size = tr[tr[p].l].size + tr[tr[p].r].size + tr[p].cnt; 20 }/*用子樹的資料來維護父節點的資料*/ 21 22 int get_node(int key) { 23 tr[++idx].key = key; 24 tr[idx].val = rand(); 25 tr[idx].cnt = tr[idx].size = 1; 26 return idx; 27
} 28 29 void zig(int &p) { /*右旋*/ 30 int q = tr[p].l; 31 tr[p].l = tr[q].r; 32 tr[q].r = p; 33 p = q; 34 pushup(tr[p].r), pushup(p); 35 } 36 37 void zag(int &p) { /*左旋*/ 38 int q = tr[p].r; 39 tr[p].r = tr[q].l; 40 tr[q].l = p; 41 p = q; 42 pushup(tr[p].l), pushup(p);
43 } 44 45 void build() { 46 get_node(-INF), get_node(INF); 47 root = 1; 48 tr[1].r = 2; 49 pushup(root); 50 if (tr[1].val < tr[2].val) zag(root); 51 } 52 53 void insert(int &p, int key) { 54 if (!p) p = get_node(key); 55 else if (tr[p].key == key) tr[p].cnt++; 56 else if (tr[p].key > key) { 57 insert(tr[p].l, key); 58 if (tr[tr[p].l].val > tr[p].val) zig(p); 59 } else { 60 insert(tr[p].r, key); 61 if (tr[tr[p].r].val > tr[p].val) zag(p); 62 } 63 pushup(p); 64 } 65 66 void remove(int &p, int key) { 67 if (!p) return; 68 if (tr[p].key == key) { 69 if (tr[p].cnt > 1) 70 tr[p].cnt--; 71 else if (tr[p].l || tr[p].r) { 72 if (!tr[p].r || tr[tr[p].l].val > tr[tr[p].r].val) { 73 zig(p); 74 remove(tr[p].r, key); 75 } else { 76 zag(p); 77 remove(tr[p].l, key); 78 } 79 } else p = 0; 80 } else if (tr[p].key > key) remove(tr[p].l, key); 81 else remove(tr[p].r, key); 82 pushup(p); 83 } 84 85 int get_rank_by_key(int p, int key) { 86 if (!p) return 0; 87 if (tr[p].key == key) return tr[tr[p].l].size + 1; 88 if (tr[p].key > key) return get_rank_by_key(tr[p].l, key); 89 return tr[tr[p].l].size + tr[p].cnt + get_rank_by_key(tr[p].r, key); 90 } 91 92 int get_key_by_rank(int p, int rank) { 93 if (!p) return INF; 94 if (tr[tr[p].l].size >= rank) return get_key_by_rank(tr[p].l, rank); 95 if (tr[tr[p].l].size + tr[p].cnt >= rank) return tr[p].key; 96 return get_key_by_rank(tr[p].r, rank - tr[tr[p].l].size - tr[p].cnt); 97 } 98 99 int get_prev(int p, int key) { 100 if (!p) return -INF; 101 if (tr[p].key >= key) return get_prev(tr[p].l, key); 102 return max(tr[p].key, get_prev(tr[p].r, key)); 103 } 104 105 int get_next(int p, int key) { 106 if (!p) return INF; 107 if (tr[p].key <= key) return get_next(tr[p].r, key); 108 return min(tr[p].key, get_next(tr[p].l, key)); 109 } 110 111 int main() { 112 build(); 113 114 scanf("%d", &n); 115 while (n--) { 116 int op, x; 117 scanf("%d%d", &op, &x); 118 if (op == 1) insert(root, x); 119 else if (op == 2) remove(root, x); 120 else if (op == 3) printf("%d\n", get_rank_by_key(root, x) - 1); 121 else if (op == 4) printf("%d\n", get_key_by_rank(root, x + 1)); 122 else if (op == 5) printf("%d\n", get_prev(root, x)); 123 else printf("%d\n", get_next(root, x)); 124 } 125 126 127 128 return 0; 129 }