avl_node *avl_remove_node(avl_node *n, avl_ft *ft){ avl_node *s = avl_next(n); if((!n->left) || (!n->right)){//no need to swap with a scapegoat return avl_remove_trunk(n, ft); } //swap all of n and s's parent, left, right, and balance fields //it would be easier to swap the data fields but that would invalidate iterators to s avl_node t = *s;//t is an automatic storage variable that holds a copy of *s if((s->left = n->left)){ s->left->parent = s; } if((s->right = n->right)){ s->right->parent = s; } if((s->parent = n->parent)){ *(s->parent->left == n ? &s->parent->left : &s->parent->right) = s;//dereference(reference) allows the ternary operator to be an lvalue } s->balance = n->balance; n->left = NULL;//s is n's inorder successor and n has a right child so s does not have a left child. if((n->right = t.right)){ n->right->parent = n; } if((n->parent = t.parent)){ *(n->parent->left == s ? &n->parent->left : &n->parent->right) = n; } n->balance = t.balance; if(t.parent == n){//s was n's child. In this case, these pointers loop back and need to be fixed. s->right = n; n->parent = s; n->right = t.right; } return avl_remove_trunk(n, ft); }
void avl() { printf(">> AVL\n"); avl_tree_t tree; avl_init(&tree, NULL); test_avl_t a = { 1 }; test_avl_t b = { 2 }; test_avl_t c = { 3 }; avl_insert(&tree, &a.node, &test_avl_compare); avl_insert(&tree, &b.node, &test_avl_compare); avl_insert(&tree, &c.node, &test_avl_compare); // Display them avl_node_t *node = avl_head(&tree); while (node) { avl_node_t *next = avl_next(node); avl_node_t *prev = avl_prev(node); test_avl_t *c = avl_ref(node, test_avl_t, node); test_avl_t *n = next ? avl_ref(next, test_avl_t, node) : NULL; test_avl_t *p = prev ? avl_ref(prev, test_avl_t, node) : NULL; printf("current: %d, next: %d, prev: %d\n", c->number, n ? n->number : -1, p ? p->number : -1); node = next; } }
static vg_prefix_t * vg_prefix_next(vg_prefix_t *vp) { avl_item_t *itemp = &vp->vp_item; itemp = avl_next(itemp); if (itemp) return avl_item_entry(itemp, vg_prefix_t, vp_item); return NULL; }
static pubkeybatch_t * pubkeybatch_avl_next(pubkeybatch_t *vp) { avl_item_t *itemp = &vp->avlent; itemp = avl_next(itemp); if (itemp) return avl_item_entry(itemp, pubkeybatch_t, avlent); return NULL; }
static workitem_t * workitem_avl_next(workitem_t *vp) { avl_item_t *itemp = &vp->avlent; itemp = avl_next(itemp); if (itemp) return avl_item_entry(itemp, workitem_t, avlent); return NULL; }
struct avl_node* avl_search_greater(struct avl_tree *tree, struct avl_node *node, avl_cmp_func *func) // if an exact match does not exist, // return smallest node greater than NODE { struct avl_node *p = tree->root; struct avl_node *pp = NULL; int cmp; while(p) { cmp = func(p, node, tree->aux); pp = p; if (cmp > 0) { p = p->left; }else if (cmp < 0){ p = p->right; }else { // search success return p; } } if (!pp) { return pp; } cmp = func(pp, node, tree->aux); if (cmp > 0) { return pp; }else{ return avl_next(pp); } }
static void avl_test() { struct avl_node *an = NULL; AVL_TREE(t, sizeof (int)); int i; struct p { int i; int v; }; struct p * p; for (i = 0; i <= 19; i++) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 0; avl_insert(&t, p); } for (i = 19; i >= 10; i--) { p = avl_remove(&t, &i); printf(" removed %d/%d\n", p->i, p->v ); debugFree( p, 1999 ); } for (i = 9; i >= 0; i--) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 1; avl_insert(&t, p); } for (i = 5; i <= 15; i++) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 2; avl_insert(&t, p); } for (i = 3; i <= 9; i++) { p = debugMalloc(sizeof ( struct p), 999); p->i = 2; p->v = i; avl_insert(&t, p); } printf("\navl_iterate():\n"); i=0; an = NULL; while( (an = avl_iterate( &t, an ) ) ) { p = ((struct p*)(an->key)); if ( i > p->i) printf("\nERROR %d > %d \n", i, p->i); i = p->i; printf( "%3d/%1d ", p->i, p->v ); } printf("\n"); #ifdef AVL_DEBUG printf("avl_debug():\n"); avl_debug( &t ); #endif for (i = 9; i >= 3; i--) { int v = 2; if ((p = avl_remove(&t, &v)) ) { printf(" removed %d/%d\n", p->i, p->v); debugFree(p, 1999); } } for (i = 9; i >= 0; i--) { if ( (p = avl_remove(&t, &i) ) ) { printf(" removed %d/%d\n", p->i, p->v); debugFree(p, 1999); } } for (i = 0; i <= 19; i++) { if ((p = avl_remove(&t, &i))) { printf(" removed %d/%d\n", p->i, p->v); debugFree(p, 1999); } else { printf(" failed rm %d\n", i); } } /* for (i = 20; i >= 0; i--) { p = debugMalloc(sizeof ( struct p), 999); p->i = i; p->v = 5; avl_insert(&t, p); } */ i = 0; printf("\n"); printf("\navl_next():\n"); int32_t j = 0; while( (an = avl_next( &t, &j )) ) { p = ((struct p*)(an->key)); j = p->i; if ( i > p->i) printf("\nERROR %d > %d \n", i, p->i); i = p->i; printf( "N%4d/%1d ", p->i, p->v ); if ( i%10 == 0 ) printf("\n"); } printf("\navl_iterate():\n"); i=0; while( (an = avl_iterate( &t, an ) ) ) { p = ((struct p*)(an->key)); if ( i > p->i) printf("\nERROR %d > %d \n", i, p->i); i = p->i; printf( "%3d/%1d ", p->i, p->v ); } printf("\n"); #ifdef AVL_DEBUG printf("avl_debug():\n"); avl_debug( &t ); #endif while( t.root ) { p = (struct p*)t.root->key; p = avl_remove( &t, p ); printf(" removed %d/%d\n", p->i, p->v ); debugFree( p, 1999 ); } printf("\n"); cleanup_all(CLEANUP_SUCCESS); }