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;
}
Exemple #3
0
/*
 *
 * 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);
}
Exemple #4
0
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;
}
Exemple #5
0
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);
		}
	}
}
Exemple #6
0
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;
}