么么达地学习平衡树。不难,看了一个下午后就懂了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; } |
原文:http://www.cnblogs.com/iwtwiioi/p/3536845.html