bag_elem_t avl_remove_min(avl_node_t **root) { bag_elem_t min; if ((*root)->left) { /* *root is not the minimum, keep going and rebalance if necessary. */ min = avl_remove_min(&(*root)->left); if (HEIGHT((*root)->left) + 1 < HEIGHT((*root)->right)) avl_rebalance_to_the_left(root); else avl_update_height(*root); } else { /* Remove *root. */ avl_node_t *old = *root; min = (*root)->elem; *root = (*root)->right; free(old); } return min; }
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); } } }