Exemple #1
0
/* Remove an element a from the AVL tree t
 * returns -1 if the depth of the tree has shrunk
 * Warning: if the element is not present in the tree,
 *          returns 0 as if it had been removed succesfully.
 */
int avl_remove(avl_tree* t, avl* a) {
	int b;
	if (t->root == a)
		return avl_removeroot(t);
	b = t->compar(t->root, a);
	if (b >= 0) {
		/* remove from the left subtree */
		int ch;
		avl_tree left_subtree;
		if ((left_subtree.root = t->root->left)) {
			left_subtree.compar = t->compar;
			ch = avl_remove(&left_subtree, a);
			t->root->left = left_subtree.root;
			if (ch) {
				switch (t->root->balance++) {
				case -1:
					return -1;
				case 0:
					return 0;
				}
				switch (t->root->right->balance) {
				case 0:
					avl_swl(&(t->root));
					t->root->balance = -1;
					t->root->left->balance = 1;
					return 0;
				case 1:
					avl_swl(&(t->root));
					t->root->balance = 0;
					t->root->left->balance = 0;
					return -1;
				}
				avl_swr(&(t->root->right));
				avl_swl(&(t->root));
				avl_nasty(t->root);
				return -1;
			}
		}
	}
	if (b <= 0) {
		/* remove from the right subtree */
		int ch;
		avl_tree right_subtree;
		if ((right_subtree.root = t->root->right)) {
			right_subtree.compar = t->compar;
			ch = avl_remove(&right_subtree, a);
			t->root->right = right_subtree.root;
			if (ch) {
				switch (t->root->balance--) {
				case 1:
					return -1;
				case 0:
					return 0;
				}
				switch (t->root->left->balance) {
				case 0:
					avl_swr(&(t->root));
					t->root->balance = 1;
					t->root->right->balance = -1;
					return 0;
				case -1:
					avl_swr(&(t->root));
					t->root->balance = 0;
					t->root->right->balance = 0;
					return -1;
				}
				avl_swl(&(t->root->left));
				avl_swr(&(t->root));
				avl_nasty(t->root);
				return -1;
			}
		}
	}
	return 0;
}
Exemple #2
0
// Remove an already-selected node n from the AVL tree t.
// Returns True if the depth of the tree has shrunk.
static Bool avl_remove(AvlTree* t, AvlNode* n)
{
   Bool ch;
   Word cmpres = cmp_key_root(t, n);

   if (cmpres < 0) {
      AvlTree left_subtree;
      // Remove from the left subtree
      vg_assert(t->root->left);
      // Only need to set the used fields in the subtree.
      left_subtree.root   = t->root->left;
      left_subtree.cmp    = t->cmp;
      left_subtree.keyOff = t->keyOff;
      ch = avl_remove(&left_subtree, n);
      t->root->left = left_subtree.root;
      if (ch) {
         switch (t->root->balance++) {
         case -1: return True;
         case  0: return False;
         }
         switch (t->root->right->balance) {
         case 0:
            avl_swl(&(t->root));
            t->root->balance = -1;
            t->root->left->balance = 1;
            return False;
         case 1:
            avl_swl(&(t->root));
            t->root->balance = 0;
            t->root->left->balance = 0;
            return True;
         }
         avl_swr(&(t->root->right));
         avl_swl(&(t->root));
         avl_nasty(t->root);
         return True;
      } else {
         return False;
      }
   
   } else if (cmpres > 0) {
      // Remove from the right subtree
      AvlTree right_subtree;
      vg_assert(t->root->right);
      // Only need to set the used fields in the subtree.
      right_subtree.root   = t->root->right;
      right_subtree.cmp    = t->cmp;
      right_subtree.keyOff = t->keyOff;
      ch = avl_remove(&right_subtree, n);
      t->root->right = right_subtree.root;
      if (ch) {
         switch (t->root->balance--) {
         case 1: return True;
         case 0: return False;
         }
         switch (t->root->left->balance) {
         case 0:
            avl_swr(&(t->root));
            t->root->balance = 1;
            t->root->right->balance = -1;
            return False;
         case -1:
            avl_swr(&(t->root));
            t->root->balance = 0;
            t->root->right->balance = 0;
            return True;
         }
         avl_swl(&(t->root->left));
         avl_swr(&(t->root));
         avl_nasty(t->root);
         return True;
      } else {
         return False;
      }

   } else {
      // Found the node to be removed.
      vg_assert(t->root == n);
      return avl_removeroot(t);
   }
}