[Olsr-cvs] olsrd-current/src lq_avl.c,1.3,1.4 lq_avl.h,1.4,1.5

Thomas Lopatic (spam-protected)
Mon Mar 26 01:19:46 CEST 2007


Update of /cvsroot/olsrd/olsrd-current/src
In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv19088/src

Modified Files:
	lq_avl.c lq_avl.h 
Log Message:
Added node deletion.


Index: lq_avl.h
===================================================================
RCS file: /cvsroot/olsrd/olsrd-current/src/lq_avl.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** lq_avl.h	10 Feb 2007 17:36:51 -0000	1.4
--- lq_avl.h	25 Mar 2007 23:19:44 -0000	1.5
***************
*** 63,66 ****
--- 63,67 ----
  struct avl_node *avl_find(struct avl_tree *, void *);
  int avl_insert(struct avl_tree *, struct avl_node *);
+ void avl_delete(struct avl_tree *, struct avl_node *);
  
  #define inline_avl_comp_ipv4(ip1, ip2) \

Index: lq_avl.c
===================================================================
RCS file: /cvsroot/olsrd/olsrd-current/src/lq_avl.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** lq_avl.c	10 Feb 2007 17:36:51 -0000	1.3
--- lq_avl.c	25 Mar 2007 23:19:44 -0000	1.4
***************
*** 256,263 ****
    node = avl_find_rec(tree->root, new->key, tree->comp);
  
!   if (0 == tree->comp) {
      diff = inline_avl_comp_ipv4(new->key, node->key);
    }
!   else {
      diff = (*tree->comp)(new->key, node->key);
    }
--- 256,266 ----
    node = avl_find_rec(tree->root, new->key, tree->comp);
  
!   if (0 == tree->comp)
!   {
      diff = inline_avl_comp_ipv4(new->key, node->key);
    }
! 
!   else
!   {
      diff = (*tree->comp)(new->key, node->key);
    }
***************
*** 297,298 ****
--- 300,545 ----
    return 0;
  }
+ 
+ static void post_delete(struct avl_tree *tree, struct avl_node *node)
+ {
+   struct avl_node *parent;
+ 
+   if ((parent = node->parent) == NULL)
+     return;
+ 
+   if (node == parent->left)
+   {
+     parent->balance++;
+ 
+     if (parent->balance == 0)
+     {
+       post_delete(tree, parent);
+       return;
+     }
+     
+     if (parent->balance == 1)
+       return;
+ 
+     if (parent->right->balance == 0)
+     {
+       rotate_left(tree, parent);
+       return;
+     }
+ 
+     if (parent->right->balance == 1)
+     {
+       rotate_left(tree, parent);
+       post_delete(tree, parent->parent);
+       return;
+     }
+ 
+     rotate_right(tree, parent->right);
+     rotate_left(tree, parent);
+     post_delete(tree, parent->parent);
+     return;
+   }
+ 
+   parent->balance--;
+ 
+   if (parent->balance == 0)
+   {
+     post_delete(tree, parent);
+     return;
+   }
+     
+   if (parent->balance == -1)
+     return;
+ 
+   if (parent->left->balance == 0)
+   {
+     rotate_right(tree, parent);
+     return;
+   }
+ 
+   if (parent->left->balance == -1)
+   {
+     rotate_right(tree, parent);
+     post_delete(tree, parent->parent);
+     return;
+   }
+ 
+   rotate_left(tree, parent->left);
+   rotate_right(tree, parent);
+   post_delete(tree, parent->parent);
+ }
+ 
+ static struct avl_node *local_min(struct avl_node *node)
+ {
+   if (node->left == NULL)
+     return node;
+ 
+   return local_min(node->left);
+ }
+ 
+ static void delete_worker(struct avl_tree *tree, struct avl_node *node)
+ {
+   struct avl_node *parent, *min;
+ 
+   parent = node->parent;
+ 
+   if (node->left == NULL && node->right == NULL)
+   {
+     if (parent == NULL)
+     {
+       tree->root = NULL;
+       return;
+     }
+ 
+     if (parent->left == node)
+     {
+       parent->left = NULL;
+       parent->balance++;
+ 
+       if (parent->balance == 1)
+         return;
+ 
+       if (parent->balance == 0)
+       {
+         post_delete(tree, parent);
+         return;
+       }
+ 
+       if (parent->right->balance == 0)
+       {
+         rotate_left(tree, parent);
+         return;
+       }
+       
+       if (parent->right->balance == 1)
+       {
+         rotate_left(tree, parent);
+         post_delete(tree, parent->parent);
+         return;
+       }
+ 
+       rotate_right(tree, parent->right);
+       rotate_left(tree, parent);
+       post_delete(tree, parent->parent);
+       return;
+     }
+ 
+     if (parent->right == node)
+     {
+       parent->right = NULL;
+       parent->balance--;
+ 
+       if (parent->balance == -1)
+         return;
+ 
+       if (parent->balance == 0)
+       {
+         post_delete(tree, parent);
+         return;
+       }
+ 
+       if (parent->left->balance == 0)
+       {
+         rotate_right(tree, parent);
+         return;
+       }
+       
+       if (parent->left->balance == -1)
+       {
+         rotate_right(tree, parent);
+         post_delete(tree, parent->parent);
+         return;
+       }
+ 
+       rotate_left(tree, parent->left);
+       rotate_right(tree, parent);
+       post_delete(tree, parent->parent);
+       return;
+     }
+   }
+ 
+   if (node->left == NULL)
+   {
+     if (parent == NULL)
+     {
+       tree->root = node->right;
+       node->right->parent = NULL;
+       return;
+     }
+ 
+     node->right->parent = parent;
+ 
+     if (parent->left == node)
+       parent->left = node->right;
+     
+     else
+       parent->right = node->right;
+ 
+     post_delete(tree, node->right);
+     return;
+   }
+ 
+   if (node->right == NULL)
+   {
+     if (parent == NULL)
+     {
+       tree->root = node->left;
+       node->left->parent = NULL;
+       return;
+     }
+ 
+     node->left->parent = parent;
+ 
+     if (parent->left == node)
+       parent->left = node->left;
+ 
+     else
+       parent->right = node->left;
+ 
+     post_delete(tree, node->left);
+     return;
+   }
+ 
+   min = local_min(node->right);
+   delete_worker(tree, min);
+   parent = node->parent;
+ 
+   min->balance = node->balance;
+   min->parent = parent;
+   min->left = node->left;
+   min->right = node->right;
+ 
+   if (min->left != NULL)
+     min->left->parent = min;
+ 
+   if (min->right != NULL)
+     min->right->parent = min;
+     
+   if (parent == NULL)
+   {
+     tree->root = min;
+     return;
+   }
+ 
+   if (parent->left == node)
+   {
+     parent->left = min;
+     return;
+   }
+ 
+   parent->right = min;
+ }
+ 
+ void avl_delete(struct avl_tree *tree, struct avl_node *node)
+ {
+   delete_worker(tree, node);
+ 
+   node->balance = 0xdeadbeef;
+ 
+   node->left = (struct avl_node *)0xdeadbeef;
+   node->right = (struct avl_node *)0xdeadbeef;
+ 
+   node->key = (void *)0xdeadbeef;
+ 
+   node->data = (void *)0xdeadbeef;
+ }
+ 





More information about the Olsr-cvs mailing list