static int avl_remove (node* tree, node** parent, data_t key) { if (!tree || !parent) return 0; int err_prev; if (tree -> data == key) { if (!tree -> child [right]) { node* tmp = tree -> child [left]; free (tree); *parent = tmp; return 0; } node *tmp_left = tree -> child [left], *tmp_right = tree -> child [right], *tmp_min = avl_get_min (tmp_right); tmp_min -> child [right] = avl_cut_min (tmp_right); tmp_min -> child [left] = tmp_left; free (tree); *parent = tmp_min; return 0; } else if (tree -> data > key) err_prev = avl_remove (tree -> child [left], &(tree -> child [left]), key); else err_prev = avl_remove (tree -> child [right], &(tree -> child [right]), key); if (!err_prev) { avl_rep_height (tree); *parent = avl_balance (tree); } return err_prev; }
static int avl_insert (node** tree, data_t data) { node* ret = *tree; int err_prev = 0; if (!(*tree)) ret = avl_create (data); else if ((*tree) -> data == data) { return 0; } else if ((*tree) -> data > data) err_prev = avl_insert (&((*tree) -> child [left]), data); else err_prev = avl_insert (&((*tree) -> child [right]), data); if (!ret) { errno = ENOMEM; return -1; } if (!err_prev) { avl_rep_height (ret); ret = avl_balance (ret); } *tree = ret; return err_prev; }
/* * * avl_insert_immediate(tree, afterp, newnode): * insert newnode immediately into tree immediately after afterp. * after insertion, newnode is right child of afterp. */ void avl_insert_immediate( avltree_desc_t *tree, avlnode_t *afterp, avlnode_t *newnode) { /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if (afterp == NULL) { tree->avl_root = newnode; tree->avl_firstino = newnode; return; } ASSERT(afterp->avl_forw == NULL); avl_insert_grow(tree, afterp, newnode, AVL_FORW); /* grow to right */ CERT(afterp->avl_forw == newnode); avl_balance(&tree->avl_root, afterp, AVL_FORW); avl_checktree(tree, tree->avl_root); }
void avl_insert(avl_tree_t **root, avl_tree_t *node){ int left_d = 0, right_d = 0; /* Break condition ... */ if( (*root) == NULL ){ (*root) = node; node->depth = 1; return; } if( (*root)->key > node->key ){ avl_insert( &((*root)->left), node); } else { if( (*root)->key < node->key ){ avl_insert( &((*root)->right), node); } else { /* (*root)->key == node->key */ EMSG("Trying to duplicate entry ...\n"); return; } } if( (*root)->left ){ left_d = (*root)->left->depth; } if( (*root)->right ){ right_d = (*root)->right->depth; } (*root)->depth = MAX(left_d, right_d) + 1; (*root)->flags = right_d - left_d; if( ((*root)->flags == AVL_FLAGS_LEFT_UNBAL) || ((*root)->flags == AVL_FLAGS_RIGHT_UNBAL) ){ avl_balance(root); } return; }
static void do_rotation(struct avltree *tree, struct avlnode *parent) { struct avlnode *node; /* do rotation */ while (parent) { int balance; struct avlnode *left, *right; node = parent; parent = node->parent; left = node->left; right = node->right; balance = avl_balance(node); if (balance < -1) { int son_balance = avl_balance(right); /* RR */ if (son_balance <= 0) { if (!parent) { lrotate(&tree->root); } else { lrotate(node == parent->left ? &parent->left : &parent->right); } continue; } /* RL */ if (son_balance > 0) { rrotate(&node->right); if (!parent) { lrotate(&tree->root); } else { lrotate(node == parent->left ? &parent->left : &parent->right); } continue; } assert(0); } else if (balance > 1) { int son_balance = avl_balance(left); /* LL */ if (son_balance >= 0) { if (!parent) { rrotate(&tree->root); } else { rrotate(node == parent->left ? &parent->left : &parent->right); } continue; } /* LR */ if (son_balance < 0) { lrotate(&node->left); if (!parent) { rrotate(&tree->root); } else { rrotate(node == parent->left ? &parent->left : &parent->right); } continue; } assert(0); } else { avl_update_height(node); } } }
avlnode_t * avl_insert( register avltree_desc_t *tree, register avlnode_t *newnode) { register avlnode_t *np; register __psunsigned_t start = AVL_START(tree, newnode); register __psunsigned_t end = AVL_END(tree, newnode); int growth; ASSERT(newnode); ASSERT(start <= end); /* * Clean all pointers for sanity; some will be reset as necessary. */ newnode->avl_nextino = NULL; newnode->avl_parent = NULL; newnode->avl_forw = NULL; newnode->avl_back = NULL; newnode->avl_balance = AVL_BALANCE; if ((np = tree->avl_root) == NULL) { /* degenerate case... */ tree->avl_root = newnode; tree->avl_firstino = newnode; return newnode; } if ((np = avl_insert_find_growth(tree, start, end, &growth)) == NULL) { if (start != end) { /* non-zero length range */ fprintf(stderr, _("avl_insert: Warning! duplicate range [%llu,%llu]\n"), (unsigned long long)start, (unsigned long long)end); } return(NULL); } avl_insert_grow(tree, np, newnode, growth); if (growth == AVL_BACK) { /* * Growing to left. if np was firstino, newnode will be firstino */ if (tree->avl_firstino == np) tree->avl_firstino = newnode; } #ifdef notneeded else if (growth == AVL_FORW) /* * Cannot possibly be firstino; there is somebody to our left. */ ; #endif newnode->avl_parent = np; CERT(np->avl_forw == newnode || np->avl_back == newnode); avl_balance(&tree->avl_root, np, growth); avl_checktree(tree, tree->avl_root); return newnode; }