コード例 #1
0
ファイル: rbt.c プロジェクト: 1587/ltp
rb_node *insert_successor_at(rb_tree * tree, rb_node * at_node, datatype object)
{
	rb_node *parent;
	rb_node *new_node;

	if (!(tree->root)) {
		/* Assign a new root node (the root is always
		 * black)
		 */
		new_node = rbnode_construct(object, black);
		if (!new_node)
			return NULL;
		tree->root = new_node;
		tree->isize = 1;
		return new_node;
	}

	/* Insert the new object as a red leaf, being the successor of
	 * node
	 */
	new_node = rbnode_construct(object, red);
	if (!new_node)
		return NULL;

	if (!at_node) {
		/* The new node should become the tree's minimum Place
		 * is as the left child of the current minimal leaf
		 */
		parent = rbnode_minimum(tree->root);
		parent->left = new_node;
	} else {
		/* Make sure the insertion does not violate the tree
		 * order In case given node has no right child, place
		 * the new node as its right child. Otherwise, place
		 * it at the leftmost position at the sub-tree rooted
		 * at its right side.
		 */
		if (!at_node->right) {
			parent = at_node;
			parent->right = new_node;
		} else {
			parent = rbnode_minimum(at_node->right);
			parent->left = new_node;
		}
	}

	new_node->parent = parent;

	/* Mark that a new node was added */
	tree->isize++;

	/* Fix the tree properties */
	rbtree_insert_fixup(tree, new_node);

	return new_node;
}
コード例 #2
0
ファイル: rbtree.c プロジェクト: CoryXie/CellOS
/*! 
 * Get the next node in the tree (according to the tree order)
 *
 * [takes O(log n) operations at worst-case, but only O(1) amortized]
 *
 * \param tree The tree
 *
 * \param node The current object
 *
 * \return The successor node, or a NULL, if we are at the tree maximum
 */
rbnode_t * rbtree_successor
    (
    rbtree_t *tree,
    rbnode_t *node
    )
    {
    rbnode_t *succ;

    /*
     * If there is a right child, the successor is the minimal
     * object in the sub-tree spanned by this child.
     */

    if (node->right != NULL)
        return rbnode_minimum(node->right);

    /*
     * Otherwise, go up the tree until reaching the parent
     * from the left direction.
     */

    succ = node->parent;

    while (succ != NULL && node == succ->right)
        {
        node = succ;
        succ = succ->parent;
        }

    return succ;
    }
コード例 #3
0
ファイル: rbt.c プロジェクト: 1587/ltp
rb_node *rbtree_minimum(rb_tree * tree)
{
	if (!(tree->root))
		return NULL;

	/* Return the leftmost leaf in the tree */
	return rbnode_minimum(tree->root);
}
コード例 #4
0
ファイル: rbt.c プロジェクト: 1587/ltp
void rbtree_remove_at(rb_tree * tree, rb_node * node, destructor d)
{
	rb_node *child = NULL;

	/* In case of deleting the single object stored in the tree,
	 * free the root, thus emptying the tree
	 */
	if (tree->isize == 1) {
		rbnode_destruct(tree->root, d);
		tree->root = NULL;
		tree->isize = 0;
		return;
	}

	/* Remove the given node from the tree */
	if (node->left && node->right) {
		/* If the node we want to remove has two children,
		 * find its successor, which is the leftmost child in
		 * its right sub-tree and has at most one child (it
		 * may have a right child).
		 */
		rb_node *succ_node = rbnode_minimum(node->right);

		/* Now physically swap node and its successor. Notice
		 * this may temporarily violate the tree properties,
		 * but we are going to remove node anyway.  This way
		 * we have moved node to a position were it is more
		 * convinient to delete it.
		 */
		int immediate_succ = (node->right == succ_node);
		rb_node *succ_parent = succ_node->parent;
		rb_node *succ_left = succ_node->left;
		rb_node *succ_right = succ_node->right;
		rb_color succ_color = succ_node->color;

		succ_node->parent = node->parent;
		succ_node->left = node->left;
		succ_node->right = immediate_succ ? node : node->right;
		succ_node->color = node->color;

		node->parent = immediate_succ ? succ_node : succ_parent;
		node->left = succ_left;
		node->right = succ_right;
		node->color = succ_color;

		if (!immediate_succ) {
			if (succ_node == node->parent->left)
				node->parent->left = node;
			else
				node->parent->right = node;
		}

		if (node->left)
			node->left->parent = node;
		if (node->right)
			node->right->parent = node;

		if (succ_node->parent) {
			if (node == succ_node->parent->left)
				succ_node->parent->left = succ_node;
			else
				succ_node->parent->right = succ_node;
		} else {
			tree->root = succ_node;
		}

		if (succ_node->left)
			succ_node->left->parent = succ_node;
		if (succ_node->right)
			succ_node->right->parent = succ_node;
	}

	/* At this stage, the node we are going to remove has at most
	 * one child
	 */
	child = (node->left) ? node->left : node->right;

	/* Splice out the node to be removed, by linking its parent
	 * straight to the removed node's single child.
	 */
	if (child)
		child->parent = node->parent;

	if (!(node->parent)) {
		/* If we are deleting the root, make the child the new
		 * tree node
		 */
		tree->root = child;
	} else {
		/* Link the removed node parent to its child */
		if (node == node->parent->left)
			node->parent->left = child;
		else
			node->parent->right = child;
	}

	/* Fix-up the red-black properties that may have been damaged:
	 * If we have just removed a black node, the black-depth
	 * property is no longer valid
	 */
	if (node->color == black && child)
		rbtree_remove_fixup(tree, child);

	/* Delete the un-necessary node (nullify both its children
	 * because the node's destructor is recursive).
	 */
	node->left = NULL;
	node->right = NULL;
	free(node);

	/* Decrease the number of objects in the tree */
	tree->isize--;
}
コード例 #5
0
ファイル: rbtree.c プロジェクト: CoryXie/CellOS
/*! 
 * Insert a new object to the tree as the a successor of a given node
 *
 * \param tree The tree
 *
 * \return The new node
 */
rbnode_t * rbtree_insert_successor_object_at
    (
    rbtree_t * tree,
    rbnode_t * at_node, 
    void * object
    )
    {
    rbnode_t * parent;
    rbnode_t * new_node;

    if (!(tree->root))
        {
        /* Assign a new root node. 
         * Notice that the root is always black 
         */
        new_node = rbnode_create(object, RB_BLACK);
        
        if (!new_node) 
            return NULL;
        
        tree->root = new_node;
        tree->size = 1;

        new_node->tree = tree;

        return new_node;
        }

    /* Insert the new object as a red leaf, being the successor of node */
    new_node = rbnode_create(object, RB_RED);
    
    if (!new_node) 
        return NULL;

    if (!at_node)
        {
        /* 
         * The new node should become the tree minimum: Place is as the left
         * child of the current minimal leaf.
         */
        parent = rbnode_minimum(tree->root);
        
        parent->left = new_node;
        }
    else
        {
        /* Make sure the insertion does not violate the tree order */

        /* 
         * In case given node has no right child, place the new node as its
         * right child. Otherwise, place it at the leftmost position at the
         * sub-tree rooted at its right side.
         */
        if (!at_node->right)
            {
            parent = at_node;
            parent->right = new_node;
            }
        else
            {
            parent = rbnode_minimum(at_node->right);
            parent->left = new_node;
            }
        }

    new_node->parent = parent;

    /* Mark that a new node was added */
    tree->size++;

    /* Fix up the tree properties */
    rbtree_insert_fixup(tree, new_node);

    new_node->tree = tree;

    return new_node;
    }