X-Git-Url: https://www.tinc-vpn.org/git/browse?p=tinc;a=blobdiff_plain;f=lib%2Favl_tree.c;h=8ec680bed6599445bf021d270bc4d11118807949;hp=34ce2a33cdc6339c46ee362eb77935ab4c2f17b7;hb=627f7c22b447bd464b536cd016278545674df93d;hpb=d3f889c8076dff9c00ebfe1459cb36425f8da41d diff --git a/lib/avl_tree.c b/lib/avl_tree.c index 34ce2a33..8ec680be 100644 --- a/lib/avl_tree.c +++ b/lib/avl_tree.c @@ -1,8 +1,8 @@ /* avl_tree.c -- avl_ tree and linked list convenience Copyright (C) 1998 Michael H. Buselli - 2000,2001 Ivo Timmermans , - 2000,2001 Guus Sliepen + 2000,2001 Ivo Timmermans , + 2000,2001 Guus Sliepen 2000,2001 Wessel Dankers This program is free software; you can redistribute it and/or modify @@ -26,10 +26,10 @@ the code. Mail me if you found a bug. Cleaned up and incorporated some of the ideas from the red-black tree - library for inclusion into tinc (http://tinc.nl.linux.org) by - Guus Sliepen . + library for inclusion into tinc (http://tinc.nl.linux.org/) by + Guus Sliepen . - $Id: avl_tree.c,v 1.1.2.3 2001/01/07 17:08:49 guus Exp $ + $Id: avl_tree.c,v 1.1.2.9 2002/06/21 10:11:11 guus Exp $ */ #include @@ -383,7 +383,7 @@ avl_node_t *avl_search_closest_smaller_node(const avl_tree_t *tree, const void * node = avl_search_closest_node(tree, data, &result); - if(result > 0) + if(result < 0) node = node->prev; return node; @@ -396,7 +396,7 @@ avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, const void * node = avl_search_closest_node(tree, data, &result); - if(result < 0) + if(result > 0) node = node->next; return node; @@ -406,12 +406,43 @@ avl_node_t *avl_search_closest_greater_node(const avl_tree_t *tree, const void * avl_node_t *avl_insert(avl_tree_t *tree, void *data) { - avl_node_t *node; + avl_node_t *closest, *new; + int result; - node = avl_alloc_node(); - node->data = data; + if (!tree->root) + { + new = avl_alloc_node(); + new->data = data; + avl_insert_top(tree, new); + } + else + { + closest = avl_search_closest_node(tree, data, &result); + switch(result) + { + case -1: + new = avl_alloc_node(); + new->data = data; + avl_insert_before(tree, closest, new); + break; + case 1: + new = avl_alloc_node(); + new->data = data; + avl_insert_after(tree, closest, new); + break; + default: + return NULL; + } + } + +#ifdef AVL_COUNT + new->count = 1; +#endif +#ifdef AVL_DEPTH + new->depth = 1; +#endif - return avl_insert_node(tree, node); + return new; } avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) @@ -433,7 +464,7 @@ avl_node_t *avl_insert_node(avl_tree_t *tree, avl_node_t *node) avl_insert_after(tree, closest, node); break; case 0: - return closest; + return NULL; } } @@ -462,6 +493,9 @@ void avl_insert_before(avl_tree_t *tree, avl_node_t *before, avl_node_t *node) node->parent = before; node->prev = before->prev; + if(before->left) + return avl_insert_after(tree, before->prev, node); + if (before->prev) before->prev->next = node; else @@ -478,6 +512,9 @@ void avl_insert_after(avl_tree_t *tree, avl_node_t *after, avl_node_t *node) if (!after) return tree->head ? avl_insert_before(tree, tree->head, node) : avl_insert_top(tree, node); + if(after->right) + return avl_insert_before(tree, after->next, node); + node->prev = after; node->parent = after; node->next = after->next; @@ -560,6 +597,15 @@ void avl_unlink_node(avl_tree_t *tree, avl_node_t *node) } avl_rebalance(tree, balnode); + + node->next = node->prev = node->parent = node->left = node->right = NULL; + +#ifdef AVL_COUNT + node->count = 0; +#endif +#ifdef AVL_DEPTH + node->depth = 0; +#endif } void avl_delete_node(avl_tree_t *tree, avl_node_t *node)