00001
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #ifdef __KERNEL__
00038
00039 # include <linux/slab.h>
00040 # include <linux/errno.h>
00041
00042 # define avl_malloc(size) kmalloc(size, GFP_KERNEL)
00043 # define avl_free(ptr) kfree(ptr)
00044 # define avl_error(...) printk(KERN_ERR __VA_ARGS__)
00045 # define avl_log(...) printk(KERN_INFO __VA_ARGS__)
00046 # define return_errno(num) return (num < 0 ? num : (0 - num))
00047
00048 #else // userspace
00049
00050 # include <stdio.h>
00051 # include <stdlib.h>
00052 # include <errno.h>
00053 # include <syslog.h>
00054
00055 # define avl_malloc(size) malloc(size)
00056 # define avl_free(ptr) free(ptr)
00057 # define avl_error(...) syslog(LOG_ERR, __VA_ARGS__)
00058 # define avl_log(...) syslog(LOG_INFO, __VA_ARGS__)
00059 # define return_errno(num) do { errno = num; return -1; } while (0)
00060
00061 #endif // __KERNEL__
00062
00063 #include "avl.h"
00064
00065 struct avlnode {
00066 void *element;
00067 unsigned long key;
00068 struct avlnode *left, *right;
00069 struct avlnode *next, *prev;
00070 unsigned int height;
00071 };
00072
00073
00074
00075 enum { LEFT = 0, RIGHT = 1 };
00076
00077
00078 static inline int maximum(int a, int b)
00079 {
00080 return a > b ? a : b;
00081 }
00082
00083 static inline int height(struct avlnode *tree)
00084 {
00085 if (tree == NULL) {
00086 return_errno(EINVAL);
00087 }
00088 return tree->height;
00089 }
00090
00091
00092 static struct avlnode *rotate(struct avlnode *node, int direction)
00093 {
00094 struct avlnode *child;
00095 if (node == NULL)
00096 return NULL;
00097
00098 if (direction == LEFT) {
00099 child = node->right;
00100 node->right = child->left;
00101 child->left = node;
00102 }
00103 else {
00104 child = node->left;
00105 node->left = child->right;
00106 child->right = node;
00107 }
00108
00109 node->height = 1 + maximum(height(node->left), height(node->right));
00110 child->height = 1 + maximum(height(child->left), height(child->right));
00111
00112 return child;
00113 }
00114
00115
00116 static struct avlnode *double_rotate(struct avlnode *node, int direction)
00117 {
00118 struct avlnode *child, *parent;
00119 if (node == NULL)
00120 return NULL;
00121
00122 if (direction == LEFT) {
00123 child = node->right;
00124 parent = child->left;
00125 child->left = parent->right;
00126 parent->right = child;
00127 node->right = parent->left;
00128 parent->left = node;
00129 }
00130 else {
00131 child = node->left;
00132 parent = child->right;
00133 child->right = parent->left;
00134 parent->left = child;
00135 node->left = parent->right;
00136 parent->right = node;
00137 }
00138 parent->height = 1 + maximum(height(parent->left), height(parent->right));
00139 node->height = 1 + maximum(height(node->left), height(node->right));
00140 child->height = 1 + maximum(height(child->left), height(child->right));
00141
00142 return parent;
00143 }
00144
00145
00146
00147
00148 static struct avlnode *__find_min_node(struct avltree *tree)
00149 {
00150 struct avlnode *node;
00151
00152 if (tree == NULL)
00153 return NULL;
00154
00155 node = tree->root;
00156 if (node == NULL)
00157 return NULL;
00158
00159 while (node->left != NULL)
00160 node = node->left;
00161
00162 return node;
00163 }
00164
00165
00166 unsigned long avl_size(struct avltree *tree)
00167 {
00168 unsigned long i = 0;
00169 struct avlnode *list;
00170
00171 for (list = __find_min_node(tree); list != NULL; list = list->next)
00172 i++;
00173
00174 return i;
00175 }
00176
00177
00178 static struct avlnode *__find(unsigned long key, struct avltree *tree)
00179 {
00180 int i = 0;
00181 struct avlnode *node;
00182
00183 if (tree == NULL)
00184 return NULL;
00185 node = tree->root;
00186
00187 while (node != NULL) {
00188 if (key == node->key)
00189 break;
00190 if (key < node->key)
00191 node = node->left;
00192 else if (key > node->key)
00193 node = node->right;
00194 i++;
00195 }
00196 return node;
00197 }
00198
00199
00200 void *avl_find(unsigned long key, struct avltree *tree)
00201 {
00202 struct avlnode *node = __find(key, tree);
00203 if (node == NULL)
00204 return NULL;
00205
00206 return node->element;
00207 }
00208
00209
00210 void *avl_find_min(struct avltree *tree)
00211 {
00212 struct avlnode *min = __find_min_node(tree);
00213 if (min == NULL)
00214 return NULL;
00215
00216 return min->element;
00217 }
00218
00219
00220
00221 struct avlnode *__find_max_node(struct avltree *tree)
00222 {
00223 struct avlnode *node;
00224
00225 if (tree == NULL)
00226 return NULL;
00227
00228 node = tree->root;
00229 if (node == NULL)
00230 return NULL;
00231
00232 while (node->right != NULL)
00233 node = node->right;
00234
00235 return node;
00236 }
00237
00238
00239 void *avl_find_max(struct avltree *tree)
00240 {
00241 struct avlnode *max = __find_max_node(tree);
00242 if (max == NULL)
00243 return NULL;
00244
00245 return max->element;
00246 }
00247
00248
00249
00250 static struct avlnode *__avl_ins(void *elt, unsigned long key,
00251 struct avlnode *tree, struct avlnode *parent,
00252 int direction, int *error)
00253 {
00254 if (tree == NULL) {
00255 tree = avl_malloc(sizeof(struct avlnode));
00256 if (tree == NULL) {
00257 *error = 1;
00258 return NULL;
00259 }
00260 tree->key = key;
00261 tree->element = elt;
00262 tree->left = tree->right = NULL;
00263 tree->next = tree->prev = NULL;
00264
00265 if (direction == LEFT) {
00266 tree->next = parent;
00267 tree->prev = parent->prev;
00268 if (parent->prev != NULL)
00269 parent->prev->next = tree;
00270 parent->prev = tree;
00271 }
00272 else if (direction == RIGHT) {
00273 tree->next = parent->next;
00274 tree->prev = parent;
00275 if (parent->next != NULL)
00276 parent->next->prev = tree;
00277 parent->next = tree;
00278 }
00279 }
00280 else if (key < tree->key) {
00281 tree->left = __avl_ins(elt, key, tree->left, tree, LEFT, error);
00282
00283 if (height(tree->left) - height(tree->right) >= 2) {
00284 if (height(tree->left->left) - height(tree->left->right) >= 1)
00285 tree = rotate(tree, RIGHT);
00286 else if (height(tree->left->right) - height(tree->left->left) >= 1)
00287 tree = double_rotate(tree, RIGHT);
00288 }
00289 }
00290 else if (key > tree->key) {
00291 tree->right = __avl_ins(elt, key, tree->right, tree, RIGHT, error);
00292
00293 if (height(tree->right) - height(tree->left) >= 2) {
00294 if (height(tree->right->right) - height(tree->right->left) >= 1)
00295 tree = rotate(tree, LEFT);
00296 else if (height(tree->right->left) - height(tree->right->right) >= 1)
00297 tree = double_rotate(tree, LEFT);
00298 }
00299 }
00300 else if (key == tree->key) {
00301 *error = 1;
00302 }
00303
00304 tree->height = 1 + maximum(height(tree->left), height(tree->right));
00305 return tree;
00306 }
00307
00308
00309
00310 int avl_insert(void *elt, unsigned long key, struct avltree *tree)
00311 {
00312 int error = 0;
00313 if (tree == NULL || elt == NULL) {
00314 return_errno(EINVAL);
00315 }
00316
00317 tree->root = __avl_ins(elt, key, tree->root, NULL, -1, &error);
00318 return error;
00319 }
00320
00321
00322
00323 static struct avlnode *__avl_del(void *elt, unsigned long key,
00324 struct avlnode *tree, struct avlnode *parent,
00325 int direction, int *error)
00326 {
00327 if (tree == NULL) {
00328 *error = 1;
00329 return NULL;
00330 }
00331 else if (key == tree->key) {
00332 elt = tree->element;
00333
00334 if (tree->next != NULL)
00335 tree->next->prev = tree->prev;
00336 if (tree->prev != NULL)
00337 tree->prev->next = tree->next;
00338 if (direction == LEFT)
00339 parent->left = NULL;
00340 else if (direction == RIGHT)
00341 parent->right = NULL;
00342 avl_free(tree);
00343
00344 return NULL;
00345 }
00346 else if (key < tree->key) {
00347 tree->left = __avl_del(elt, key, tree->right, tree, LEFT, error);
00348
00349 if (height(tree->left) - height(tree->right) >= 2) {
00350 if (height(tree->left->left) - height(tree->left->right) >= 1)
00351 tree = rotate(tree, RIGHT);
00352 else if (height(tree->left->right) - height(tree->left->left) >= 1)
00353 tree = double_rotate(tree, RIGHT);
00354 }
00355 } else if (key > tree->key) {
00356 tree->right = __avl_del(elt, key, tree->right, tree, RIGHT, error);
00357
00358 if (height(tree->right) - height(tree->left) >= 2) {
00359 if (height(tree->right->right) - height(tree->right->left) >= 1)
00360 tree = rotate(tree, LEFT);
00361 else if (height(tree->right->left) - height(tree->right->right) >= 1)
00362 tree = double_rotate(tree, LEFT);
00363 }
00364 }
00365
00366 tree->height = 1 + maximum(height(tree->left), height(tree->right));
00367 return tree;
00368 }
00369
00370
00371 int avl_delete(void *elt, unsigned long key, struct avltree *tree)
00372 {
00373 int error = 0;
00374 if (tree == NULL) {
00375 return_errno(EINVAL);
00376 }
00377
00378 tree->root = __avl_del(elt, key, tree->root, NULL, -1, &error);
00379 return error;
00380 }
00381
00382
00383 static void __destroy_branch(struct avlnode *root)
00384 {
00385 if (root != NULL) {
00386 __destroy_branch(root->left);
00387 __destroy_branch(root->right);
00388 avl_free(root);
00389 }
00390 }
00391
00392
00393 void destroy_avltree(struct avltree *tree)
00394 {
00395 if (tree != NULL)
00396 __destroy_branch(tree->root);
00397 }
00398
00399
00400
00401
00402
00403 static void __avl_print(struct avlnode *tree, int direction, int indent)
00404 {
00405 int i;
00406 if (tree != NULL) {
00407 __avl_print(tree->right, RIGHT, indent + 1);
00408
00409 for (i = 0; i < indent - 1; i++)
00410 avl_log(" ");
00411 if (indent) {
00412 if (direction == LEFT)
00413 avl_log(" \\-- ");
00414 else
00415 avl_log(" /-- ");
00416 }
00417 avl_log("%ld\n", tree->key);
00418
00419 __avl_print(tree->left, LEFT, indent + 1);
00420 }
00421 }
00422
00423
00424 void avl_print(struct avltree *tree)
00425 {
00426 if (tree == NULL)
00427 return;
00428
00429 avl_log("AVL tree: \n");
00430 __avl_print(tree->root, -1, 0);
00431 }
00432
00433
00434 void avl_print_list(struct avltree *tree)
00435 {
00436 int i;
00437 struct avlnode *list = __find_min_node(tree);
00438
00439 if (list == NULL)
00440 return;
00441
00442 avl_log("Linked list: %ld ", list->key);
00443 for (i = 1, list = list->next; list != NULL; list = list->next, i++)
00444 avl_log("-> %ld ", list->key);
00445 avl_log("\n\n");
00446 }