Exemplo n.º 1
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;
}
Exemplo n.º 2
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;
}