平衡树

么么达地学习平衡树。不难,看了一个下午后就懂了treap。首先放上treap的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
 
#define NEW(d) new treap(d)
 
struct treap {
    treap* ch[2];
    int key, s;
    treap() : key(0), s(rand()) { ch[0] = ch[1] = NULL; }
    treap(int d) : key(d), s(rand()) { ch[0] = ch[1] = NULL; }
    bool operator< (const treap& a) { return s < a.s ? 1 : 0; }
    int cmp(int d) {
        if(key == d) return -1;
        return key > d ? 0 : 1;
    }
}*root = NULL;
 
typedef treap* tree;
 
//左右旋,这里用的技巧是在lrj白书上看到的,旋转不多说,自己理解
void rot(tree& rt, int d) {
    tree k = rt-> ch[d^1]; rt-> ch[d^1] = k-> ch[d]; k-> ch[d] = rt; rt = k;
}
 
void insert(tree& rt, int d) {
    if(rt == NULL) rt = NEW(d);
    else {
        int p = (rt-> key > d ? 0: 1);
        insert(rt-> ch[p], d);
        if(rt < rt-> ch[d]) rot(rt, p^1); //先插入再旋转
    }
}
 
void del(tree& rt, int d) {
    if(rt == NULL) return;
    int c = rt-> cmp(d);
    //如果找到节点
    if(c == -1) {
        //如果有左右子女
        if(rt-> ch[0] != NULL && rt-> ch[1] != NULL) {
            int p = (rt-> ch[1] < rt-> ch[0] ? 1 : 0);
            rot(rt, p); del(rt-> ch[p], d);
        }
        //如果没有子女或只有一个子女
        else {
            tree t = rt;
            if(rt-> ch[0] == NULL) rt = rt-> ch[1]; else rt = rt-> ch[0];
            delete t;
        }
    }
    //如果没找到节点
    else
        del(rt-> ch[c], d);
}
 
tree search(int d) {
    if(root == NULL) return root;
    tree ret = root; int c = ret-> cmp(d);
    while(ret != NULL && c != -1) ret = ret-> ch[c], c = ret-> cmp(d);
    return ret;
}
 
tree max(){
    if(root == NULL) return NULL;
    tree ret = root;
    while(ret-> ch[1]) ret = ret-> ch[1];
    return ret;
}
 
tree min(){
    if(root == NULL) return NULL;
    tree ret = root;
    while(ret-> ch[0]) ret = ret-> ch[0];
    return ret;
}
 
void out(string str) {
    cout << str;
}
 
int main() {
    out("1: insert\n2: del\n3: search\n4: max\n5: min\n");
    int c, t;
    tree a;
    while(cin >> c) {
        switch(c) {
        case 1: cin >> t;
                insert(root, t);
                break;
        case 2: cin >> t;
                del(root, t);
                break;
        case 3: cin >> t;
                if(search(t) == NULL) out("Not here\n");
                else out("Is here!\n");
                break;
        case 4: a = max();
                if(a != NULL) cout << a-> key << endl;
                else out("Warn!\n");
                break;
        case 5: a = min();
                if(a != NULL) cout << a-> key << endl;
                else out("Warn!\n");
                break;
        default:
                break;
        }
    }
    return 0;
}

  

平衡树

上一篇:正则这个小东东


下一篇:usaco1.3Calf Flac(枚举)