Esempio n. 1
0
/* delete an node from tree */
static avl_node_t* avl_remove_node(avl_node_t* root, avl_key_t key)
{
    int factor = 0;
    int rotate = 0;
    if (root == NULL)
        return NULL;
    if (key < root->key)
    {
        root->left = avl_remove_node(root->left, key);
    }
    else if (key > root->key)
    {
        root->right = avl_remove_node(root->right, key);
    }
    else   /* this is the node to be deleted */
    {
        if ((root->left == NULL) || (root->right == NULL))
        {
            avl_node_t* node = (root->left ? root->left : root->right);
            if (node != NULL)  /* one child case */
            {
                *root = *node;
            }
            else  /* no child case */
            {
                node = root;
                root = NULL;
            }
            avl_free_node(node);
        }
        else  /* node with two children */
        {
            avl_node_t* node = avl_node_min(root->right);
            root->key = node->key;
            root->data = node->data;
            root->right = avl_remove_node(root->right, node->key);
        }
    }

    if (root == NULL)
        return NULL;
    root->height = MAX(HEIGHT(root->left), HEIGHT(root->right)) + 1;
    factor = avl_get_balance(root);
    if (factor > 1)
    {
        int left_balance = avl_get_balance(root->left);
        rotate = (left_balance >= 0 ? ROT_LEFT : ROT_RIGHT);
    }
    else if (factor < -1)
    {
        int right_balance = avl_get_balance(root->right);
        rotate = (right_balance <= 0 ? ROT_RIGHT : ROT_LEFT);
    }
    return avl_balance_node(root, factor, rotate);
}
Esempio n. 2
0
int32_t bs_avl_remove(bs_avl_t* avl, avl_data_t data)
{
	avl->root = (void*)avl_remove_node(avl, (avl_node_t*)avl->root, data);

	bs_debug("height diff:%d\n", avl_get_balance((avl_node_t*)avl->root));
	return 0;
}
Esempio n. 3
0
static avl_node_t* avl_rebalance(avl_node_t *root)
{
	avl_node_t *node = root;
	int32_t height_diff = avl_get_balance(root);

	if(height_diff > 1)
	{
		//bs_debug("rebalance! hight diff:%d, %d\n", height_diff, root->data);
		if(avl_get_balance(node->left_child) > 0)
		{
			node = avl_rotate_ll(root);
		}
		else
		{
			node = avl_rotate_lr(root);
		}
	}
	else if(height_diff < -1)
	{
		//bs_debug("rebalance! hight diff:%d, %d\n", height_diff, root->data);
		if(avl_get_balance(node->right_child) < 0)
		{
			node = avl_rotate_rr(root);
		}
		else
		{
			node = avl_rotate_rl(root);
		}
	}
	else
	{
		//bs_debug("do not rebalance :%d  \n", root->data);
	}

	return node;
}
Esempio n. 4
0
/* insert an node to tree */
static avl_node_t* avl_insert_node(avl_node_t* root, avl_key_t key, void* data)
{
    int rotate = 0;
    if (root == NULL)
    {
        return avl_new_node(key, data);
    }
    if (key < root->key)
    {
        rotate = ROT_LEFT;
        root->left = avl_insert_node(root->left, key, data);
    }
    else if (key > root->key)
    {
        rotate = ROT_RIGHT;
        root->right = avl_insert_node(root->right, key, data);
    }
    else
        assert(!"duplicated key insertion not supported");

    /* update height */
    root->height = MAX(HEIGHT(root->left), HEIGHT(root->right)) + 1;
    return avl_balance_node(root, avl_get_balance(root), rotate);
}
void tree_print(tree_node *tn) {
    avl_node *node = (avl_node*)tn;
    printf("%d :: %d -> %d", avl_get_height(node), avl_get_balance(node), *(int*)node->value);
}