Example #1
0
/* Remove the root of the AVL tree *rootp.
 * Warning: dumps core if *rootp is empty
 */
static
Bool avl_removeroot_wrk ( AvlNode** rootp,
                          Word(*kCmp)(Word,Word) )
{
    Bool     ch;
    AvlNode* a;
    if (!(*rootp)->left) {
        if (!(*rootp)->right) {
            (*rootp) = 0;
            return True;
        }
        (*rootp) = (*rootp)->right;
        return True;
    }
    if (!(*rootp)->right) {
        (*rootp) = (*rootp)->left;
        return True;
    }
    if ((*rootp)->balance < 0) {
        /* remove from the left subtree */
        a = (*rootp)->left;
        while (a->right) a = a->right;
    } else {
        /* remove from the right subtree */
        a = (*rootp)->right;
        while (a->left) a = a->left;
    }
    ch = avl_remove_wrk(rootp, a, kCmp);
    a->left    = (*rootp)->left;
    a->right   = (*rootp)->right;
    a->balance = (*rootp)->balance;
    (*rootp)   = a;
    if(a->balance == 0) return ch;
    return False;
}
Example #2
0
// Delete key from fm, returning associated val if found
Bool delFromFM ( WordFM* fm, /*OUT*/Word* oldV, Word key )
{
    AvlNode* node = avl_find_node( fm->root, key, fm->kCmp );
    if (node) {
        avl_remove_wrk( &fm->root, node, fm->kCmp );
        if (oldV)
            *oldV = node->val;
        fm->dealloc(node);
        return True;
    } else {
        return False;
    }
}
Example #3
0
/* Remove an element a from the AVL tree t.  a must be part of
   the tree.  Returns True if the depth of the tree has shrunk.
*/
static
Bool avl_remove_wrk ( AvlNode** rootp,
                      AvlNode*  a,
                      Word(*kCmp)(Word,Word) )
{
    Bool ch;
    Word cmpres = kCmp( (*rootp)->key, a->key );

    if (cmpres > 0) {
        /* remove from the left subtree */
        AvlNode* left_subtree = (*rootp)->left;
        assert(left_subtree);
        ch = avl_remove_wrk(&left_subtree, a, kCmp);
        (*rootp)->left=left_subtree;
        if (ch) {
            switch ((*rootp)->balance++) {
            case -1:
                return True;
            case  0:
                return False;
            case  1:
                break;
            default:
                assert(0);
            }
            switch ((*rootp)->right->balance) {
            case 0:
                avl_swl( rootp );
                (*rootp)->balance = -1;
                (*rootp)->left->balance = 1;
                return False;
            case 1:
                avl_swl( rootp );
                (*rootp)->balance = 0;
                (*rootp)->left->balance = 0;
                return -1;
            case -1:
                break;
            default:
                assert(0);
            }
            avl_swr( &((*rootp)->right) );
            avl_swl( rootp );
            avl_nasty( *rootp );
            return True;
        }
    }
    else if (cmpres < 0) {
        /* remove from the right subtree */
        AvlNode* right_subtree = (*rootp)->right;
        assert(right_subtree);
        ch = avl_remove_wrk(&right_subtree, a, kCmp);
        (*rootp)->right = right_subtree;
        if (ch) {
            switch ((*rootp)->balance--) {
            case  1:
                return True;
            case  0:
                return False;
            case -1:
                break;
            default:
                assert(0);
            }
            switch ((*rootp)->left->balance) {
            case 0:
                avl_swr( rootp );
                (*rootp)->balance = 1;
                (*rootp)->right->balance = -1;
                return False;
            case -1:
                avl_swr( rootp );
                (*rootp)->balance = 0;
                (*rootp)->right->balance = 0;
                return True;
            case 1:
                break;
            default:
                assert(0);
            }
            avl_swl( &((*rootp)->left) );
            avl_swr( rootp );
            avl_nasty( *rootp );
            return True;
        }
    }
    else {
        assert(cmpres == 0);
        assert((*rootp)==a);
        return avl_removeroot_wrk(rootp, kCmp);
    }
    return 0;
}
Example #4
0
/* Remove an element a from the AVL tree t.  a must be part of
   the tree.  Returns True if the depth of the tree has shrunk. 
*/
static
Bool avl_remove_wrk ( AvlNode** rootp, 
                      AvlNode*  a, 
                      Word(*kCmp)(UWord,UWord) )
{
   Bool ch;
   Word cmpres;
   cmpres = kCmp ? /*boxed*/   kCmp( (*rootp)->key, a->key )
                 : /*unboxed*/ cmp_unsigned_Words( (UWord)(*rootp)->key,
                                                   (UWord)a->key );

   if (cmpres > 0){
      /* remove from the left subtree */
      AvlNode* left_subtree = (*rootp)->child[0];
      tl_assert(left_subtree);
      ch = avl_remove_wrk(&left_subtree, a, kCmp);
      (*rootp)->child[0]=left_subtree;
      if (ch) {
         switch ((*rootp)->balance++) {
            case -1: return True;
            case  0: return False;
            case  1: break;
            default: tl_assert(0);
         }
         switch ((*rootp)->child[1]->balance) {
            case 0:
               avl_swl( rootp );
               (*rootp)->balance = -1;
               (*rootp)->child[0]->balance = 1;
               return False;
            case 1: 
               avl_swl( rootp );
               (*rootp)->balance = 0;
               (*rootp)->child[0]->balance = 0;
               return True;
            case -1:
               break;
            default:
               tl_assert(0);
         }
         avl_swr( &((*rootp)->child[1]) );
         avl_swl( rootp );
         avl_nasty( *rootp );
         return True;
      }
   }
   else
   if (cmpres < 0) {
      /* remove from the right subtree */
      AvlNode* right_subtree = (*rootp)->child[1];
      tl_assert(right_subtree);
      ch = avl_remove_wrk(&right_subtree, a, kCmp);
      (*rootp)->child[1] = right_subtree;
      if (ch) {
         switch ((*rootp)->balance--) {
            case  1: return True;
            case  0: return False;
            case -1: break;
            default: tl_assert(0);
         }
         switch ((*rootp)->child[0]->balance) {
            case 0:
               avl_swr( rootp );
               (*rootp)->balance = 1;
               (*rootp)->child[1]->balance = -1;
               return False;
            case -1:
               avl_swr( rootp );
               (*rootp)->balance = 0;
               (*rootp)->child[1]->balance = 0;
               return True;
            case 1:
               break;
            default:
               tl_assert(0);
         }
         avl_swl( &((*rootp)->child[0]) );
         avl_swr( rootp );
         avl_nasty( *rootp );
         return True;
      }
   }
   else {
      tl_assert(cmpres == 0);
      tl_assert((*rootp)==a);
      return avl_removeroot_wrk(rootp, kCmp);
   }
   return 0;
}