caddr_t avl_delete( Avlnode **root, void *data, IFP fcmp ) { int shorter; return ravl_delete( root, (caddr_t)data, fcmp, &shorter ); }
/* * container_ravl_delete -- (internal) deletes the container */ static void container_ravl_destroy(struct block_container *bc) { struct block_container_ravl *c = (struct block_container_ravl *)bc; ravl_delete(c->tree); Free(bc); }
static caddr_t ravl_delete( Avlnode **root, caddr_t data, IFP fcmp, int *shorter ) { int shortersubtree = 0; int cmp; caddr_t savedata; Avlnode *minnode, *savenode; if ( *root == NULLAVL ) return( 0 ); cmp = (*fcmp)( data, (*root)->avl_data ); /* found it! */ if ( cmp == 0 ) { savenode = *root; savedata = savenode->avl_data; /* simple cases: no left child */ if ( (*root)->avl_left == 0 ) { *root = (*root)->avl_right; *shorter = 1; free( (char *) savenode ); return( savedata ); /* no right child */ } else if ( (*root)->avl_right == 0 ) { *root = (*root)->avl_left; *shorter = 1; free( (char *) savenode ); return( savedata ); } /* * avl_getmin will return to us the smallest node greater * than the one we are trying to delete. deleting this node * from the right subtree is guaranteed to end in one of the * simple cases above. */ minnode = (*root)->avl_right; while ( minnode->avl_left != NULLAVL ) minnode = minnode->avl_left; /* swap the data */ (*root)->avl_data = minnode->avl_data; minnode->avl_data = savedata; savedata = ravl_delete( &(*root)->avl_right, data, fcmp, &shortersubtree ); if ( shortersubtree ) *shorter = right_balance( root ); else *shorter = 0; /* go left */ } else if ( cmp < 0 ) { if ( (savedata = ravl_delete( &(*root)->avl_left, data, fcmp, &shortersubtree )) == 0 ) { *shorter = 0; return( 0 ); } /* left subtree shorter? */ if ( shortersubtree ) *shorter = left_balance( root ); else *shorter = 0; /* go right */ } else { if ( (savedata = ravl_delete( &(*root)->avl_right, data, fcmp, &shortersubtree )) == 0 ) { *shorter = 0; return( 0 ); } if ( shortersubtree ) *shorter = right_balance( root ); else *shorter = 0; } return( savedata ); }