OLD | NEW |
1 #include <stdlib.h> | 1 #include <stdlib.h> |
2 #include <search.h> | 2 #include <search.h> |
3 | 3 |
4 /* | 4 /* |
5 avl tree implementation using recursive functions | 5 avl tree implementation using recursive functions |
6 the height of an n node tree is less than 1.44*log2(n+2)-1 | 6 the height of an n node tree is less than 1.44*log2(n+2)-1 |
7 (so the max recursion depth in case of a tree with 2^32 nodes is 45) | 7 (so the max recursion depth in case of a tree with 2^32 nodes is 45) |
8 */ | 8 */ |
9 | 9 |
10 struct node { | 10 struct node { |
11 » const void *key; | 11 const void* key; |
12 » struct node *left; | 12 struct node* left; |
13 » struct node *right; | 13 struct node* right; |
14 » int height; | 14 int height; |
15 }; | 15 }; |
16 | 16 |
17 static int delta(struct node *n) { | 17 static int delta(struct node* n) { |
18 » return (n->left ? n->left->height:0) - (n->right ? n->right->height:0); | 18 return (n->left ? n->left->height : 0) - (n->right ? n->right->height : 0); |
19 } | 19 } |
20 | 20 |
21 static void updateheight(struct node *n) { | 21 static void updateheight(struct node* n) { |
22 » n->height = 0; | 22 n->height = 0; |
23 » if (n->left && n->left->height > n->height) | 23 if (n->left && n->left->height > n->height) |
24 » » n->height = n->left->height; | 24 n->height = n->left->height; |
25 » if (n->right && n->right->height > n->height) | 25 if (n->right && n->right->height > n->height) |
26 » » n->height = n->right->height; | 26 n->height = n->right->height; |
27 » n->height++; | 27 n->height++; |
28 } | 28 } |
29 | 29 |
30 static struct node *rotl(struct node *n) { | 30 static struct node* rotl(struct node* n) { |
31 » struct node *r = n->right; | 31 struct node* r = n->right; |
32 » n->right = r->left; | 32 n->right = r->left; |
33 » r->left = n; | 33 r->left = n; |
34 » updateheight(n); | 34 updateheight(n); |
35 » updateheight(r); | 35 updateheight(r); |
36 » return r; | 36 return r; |
37 } | 37 } |
38 | 38 |
39 static struct node *rotr(struct node *n) { | 39 static struct node* rotr(struct node* n) { |
40 » struct node *l = n->left; | 40 struct node* l = n->left; |
41 » n->left = l->right; | 41 n->left = l->right; |
42 » l->right = n; | 42 l->right = n; |
43 » updateheight(n); | 43 updateheight(n); |
44 » updateheight(l); | 44 updateheight(l); |
45 » return l; | 45 return l; |
46 } | 46 } |
47 | 47 |
48 static struct node *balance(struct node *n) { | 48 static struct node* balance(struct node* n) { |
49 » int d = delta(n); | 49 int d = delta(n); |
50 | 50 |
51 » if (d < -1) { | 51 if (d < -1) { |
52 » » if (delta(n->right) > 0) | 52 if (delta(n->right) > 0) |
53 » » » n->right = rotr(n->right); | 53 n->right = rotr(n->right); |
54 » » return rotl(n); | 54 return rotl(n); |
55 » } else if (d > 1) { | 55 } else if (d > 1) { |
56 » » if (delta(n->left) < 0) | 56 if (delta(n->left) < 0) |
57 » » » n->left = rotl(n->left); | 57 n->left = rotl(n->left); |
58 » » return rotr(n); | 58 return rotr(n); |
59 » } | 59 } |
60 » updateheight(n); | 60 updateheight(n); |
61 » return n; | 61 return n; |
62 } | 62 } |
63 | 63 |
64 static struct node *find(struct node *n, const void *k, | 64 static struct node* find(struct node* n, |
65 » int (*cmp)(const void *, const void *)) | 65 const void* k, |
66 { | 66 int (*cmp)(const void*, const void*)) { |
67 » int c; | 67 int c; |
68 | 68 |
69 » if (!n) | 69 if (!n) |
70 » » return 0; | 70 return 0; |
71 » c = cmp(k, n->key); | 71 c = cmp(k, n->key); |
72 » if (c == 0) | 72 if (c == 0) |
73 » » return n; | 73 return n; |
74 » if (c < 0) | 74 if (c < 0) |
75 » » return find(n->left, k, cmp); | 75 return find(n->left, k, cmp); |
76 » else | 76 else |
77 » » return find(n->right, k, cmp); | 77 return find(n->right, k, cmp); |
78 } | 78 } |
79 | 79 |
80 static struct node *insert(struct node *n, const void *k, | 80 static struct node* insert(struct node* n, |
81 » int (*cmp)(const void *, const void *), struct node **found) | 81 const void* k, |
82 { | 82 int (*cmp)(const void*, const void*), |
83 » struct node *r; | 83 struct node** found) { |
84 » int c; | 84 struct node* r; |
| 85 int c; |
85 | 86 |
86 » if (!n) { | 87 if (!n) { |
87 » » n = malloc(sizeof *n); | 88 n = malloc(sizeof *n); |
88 » » if (n) { | 89 if (n) { |
89 » » » n->key = k; | 90 n->key = k; |
90 » » » n->left = n->right = 0; | 91 n->left = n->right = 0; |
91 » » » n->height = 1; | 92 n->height = 1; |
92 » » } | 93 } |
93 » » *found = n; | 94 *found = n; |
94 » » return n; | 95 return n; |
95 » } | 96 } |
96 » c = cmp(k, n->key); | 97 c = cmp(k, n->key); |
97 » if (c == 0) { | 98 if (c == 0) { |
98 » » *found = n; | 99 *found = n; |
99 » » return 0; | 100 return 0; |
100 » } | 101 } |
101 » r = insert(c < 0 ? n->left : n->right, k, cmp, found); | 102 r = insert(c < 0 ? n->left : n->right, k, cmp, found); |
102 » if (r) { | 103 if (r) { |
103 » » if (c < 0) | 104 if (c < 0) |
104 » » » n->left = r; | 105 n->left = r; |
105 » » else | 106 else |
106 » » » n->right = r; | 107 n->right = r; |
107 » » r = balance(n); | 108 r = balance(n); |
108 » } | 109 } |
109 » return r; | 110 return r; |
110 } | 111 } |
111 | 112 |
112 static struct node *remove_rightmost(struct node *n, struct node **rightmost) | 113 static struct node* remove_rightmost(struct node* n, struct node** rightmost) { |
113 { | 114 if (!n->right) { |
114 » if (!n->right) { | 115 *rightmost = n; |
115 » » *rightmost = n; | 116 return n->left; |
116 » » return n->left; | 117 } |
117 » } | 118 n->right = remove_rightmost(n->right, rightmost); |
118 » n->right = remove_rightmost(n->right, rightmost); | 119 return balance(n); |
119 » return balance(n); | |
120 } | 120 } |
121 | 121 |
122 static struct node *remove(struct node **n, const void *k, | 122 static struct node* remove(struct node** n, |
123 » int (*cmp)(const void *, const void *), struct node *parent) | 123 const void* k, |
124 { | 124 int (*cmp)(const void*, const void*), |
125 » int c; | 125 struct node* parent) { |
| 126 int c; |
126 | 127 |
127 » if (!*n) | 128 if (!*n) |
128 » » return 0; | 129 return 0; |
129 » c = cmp(k, (*n)->key); | 130 c = cmp(k, (*n)->key); |
130 » if (c == 0) { | 131 if (c == 0) { |
131 » » struct node *r = *n; | 132 struct node* r = *n; |
132 » » if (r->left) { | 133 if (r->left) { |
133 » » » r->left = remove_rightmost(r->left, n); | 134 r->left = remove_rightmost(r->left, n); |
134 » » » (*n)->left = r->left; | 135 (*n)->left = r->left; |
135 » » » (*n)->right = r->right; | 136 (*n)->right = r->right; |
136 » » » *n = balance(*n); | 137 *n = balance(*n); |
137 » » } else | 138 } else |
138 » » » *n = r->right; | 139 *n = r->right; |
139 » » free(r); | 140 free(r); |
140 » » return parent; | 141 return parent; |
141 » } | 142 } |
142 » if (c < 0) | 143 if (c < 0) |
143 » » parent = remove(&(*n)->left, k, cmp, *n); | 144 parent = remove(&(*n)->left, k, cmp, *n); |
144 » else | 145 else |
145 » » parent = remove(&(*n)->right, k, cmp, *n); | 146 parent = remove(&(*n)->right, k, cmp, *n); |
146 » if (parent) | 147 if (parent) |
147 » » *n = balance(*n); | 148 *n = balance(*n); |
148 » return parent; | 149 return parent; |
149 } | 150 } |
150 | 151 |
151 void *tdelete(const void *restrict key, void **restrict rootp, | 152 void* tdelete(const void* restrict key, |
152 » int(*compar)(const void *, const void *)) | 153 void** restrict rootp, |
153 { | 154 int (*compar)(const void*, const void*)) { |
154 » if (!rootp) | 155 if (!rootp) |
155 » » return 0; | 156 return 0; |
156 » struct node *n = *rootp; | 157 struct node* n = *rootp; |
157 » struct node *ret; | 158 struct node* ret; |
158 » /* last argument is arbitrary non-null pointer | 159 /* last argument is arbitrary non-null pointer |
159 » which is returned when the root node is deleted */ | 160 which is returned when the root node is deleted */ |
160 » ret = remove(&n, key, compar, n); | 161 ret = remove(&n, key, compar, n); |
161 » *rootp = n; | 162 *rootp = n; |
162 » return ret; | 163 return ret; |
163 } | 164 } |
164 | 165 |
165 void *tfind(const void *key, void *const *rootp, | 166 void* tfind(const void* key, |
166 » int(*compar)(const void *, const void *)) | 167 void* const* rootp, |
167 { | 168 int (*compar)(const void*, const void*)) { |
168 » if (!rootp) | 169 if (!rootp) |
169 » » return 0; | 170 return 0; |
170 » return find(*rootp, key, compar); | 171 return find(*rootp, key, compar); |
171 } | 172 } |
172 | 173 |
173 void *tsearch(const void *key, void **rootp, | 174 void* tsearch(const void* key, |
174 » int (*compar)(const void *, const void *)) | 175 void** rootp, |
175 { | 176 int (*compar)(const void*, const void*)) { |
176 » struct node *update; | 177 struct node* update; |
177 » struct node *ret; | 178 struct node* ret; |
178 » if (!rootp) | 179 if (!rootp) |
179 » » return 0; | 180 return 0; |
180 » update = insert(*rootp, key, compar, &ret); | 181 update = insert(*rootp, key, compar, &ret); |
181 » if (update) | 182 if (update) |
182 » » *rootp = update; | 183 *rootp = update; |
183 » return ret; | 184 return ret; |
184 } | 185 } |
185 | 186 |
186 static void walk(const struct node *r, void (*action)(const void *, VISIT, int),
int d) | 187 static void walk(const struct node* r, |
187 { | 188 void (*action)(const void*, VISIT, int), |
188 » if (r == 0) | 189 int d) { |
189 » » return; | 190 if (r == 0) |
190 » if (r->left == 0 && r->right == 0) | 191 return; |
191 » » action(r, leaf, d); | 192 if (r->left == 0 && r->right == 0) |
192 » else { | 193 action(r, leaf, d); |
193 » » action(r, preorder, d); | 194 else { |
194 » » walk(r->left, action, d+1); | 195 action(r, preorder, d); |
195 » » action(r, postorder, d); | 196 walk(r->left, action, d + 1); |
196 » » walk(r->right, action, d+1); | 197 action(r, postorder, d); |
197 » » action(r, endorder, d); | 198 walk(r->right, action, d + 1); |
198 » } | 199 action(r, endorder, d); |
| 200 } |
199 } | 201 } |
200 | 202 |
201 void twalk(const void *root, void (*action)(const void *, VISIT, int)) | 203 void twalk(const void* root, void (*action)(const void*, VISIT, int)) { |
202 { | 204 walk(root, action, 0); |
203 » walk(root, action, 0); | |
204 } | 205 } |
OLD | NEW |