Exemple #1
0
/*
 * Search for the node which contains "value".  The algorithm is a
 * simple binary tree search.
 *
 * return value:
 *	NULL: the value is not in the AVL tree
 *		*where (if not NULL)  is set to indicate the insertion point
 *	"void *"  of the found tree node
 */
void *
avl_find(avl_tree_t *tree, const void *value, avl_index_t *where)
{
	avl_node_t *node;
	avl_node_t *prev = NULL;
	int child = 0;
	int diff;
	size_t off = tree->avl_offset;

	for (node = tree->avl_root; node != NULL;
	    node = node->avl_child[child]) {

		prev = node;

		diff = tree->avl_compar(value, AVL_NODE2DATA(node, off));
		ASSERT(-1 <= diff && diff <= 1);
		if (diff == 0) {
#ifdef DEBUG
			if (where != NULL)
				*where = 0;
#endif
			return (AVL_NODE2DATA(node, off));
		}
		child = avl_balance2child[1 + diff];

	}

	if (where != NULL)
		*where = AVL_MKINDEX(prev, child);

	return (NULL);
}
Exemple #2
0
/*
 * Insert "new_data" in "tree" in the given "direction" either after or
 * before (AVL_AFTER, AVL_BEFORE) the data "here".
 *
 * Insertions can only be done at empty leaf points in the tree, therefore
 * if the given child of the node is already present we move to either
 * the AVL_PREV or AVL_NEXT and reverse the insertion direction. Since
 * every other node in the tree is a leaf, this always works.
 *
 * To help developers using this interface, we assert that the new node
 * is correctly ordered at every step of the way in DEBUG kernels.
 */
void
avl_insert_here(
	avl_tree_t *tree,
	void *new_data,
	void *here,
	int direction)
{
	avl_node_t *node;
	int child = direction;	/* rely on AVL_BEFORE == 0, AVL_AFTER == 1 */
#ifdef DEBUG
	int diff;
#endif

	//ASSERT(tree != NULL);
	//ASSERT(new_data != NULL);
	//ASSERT(here != NULL);
	//ASSERT(direction == AVL_BEFORE || direction == AVL_AFTER);

	/*
	 * If corresponding child of node is not NULL, go to the neighboring
	 * node and reverse the insertion direction.
	 */
	node = AVL_DATA2NODE(here, tree->avl_offset);

#ifdef DEBUG
	diff = tree->avl_compar(new_data, here);
	//ASSERT(-1 <= diff && diff <= 1);
	//ASSERT(diff != 0);
	//ASSERT(diff > 0 ? child == 1 : child == 0);
#endif

	if (node->avl_child[child] != NULL) {
		node = node->avl_child[child];
		child = 1 - child;
		while (node->avl_child[child] != NULL) {
#ifdef DEBUG
			diff = tree->avl_compar(new_data,
			    AVL_NODE2DATA(node, tree->avl_offset));
			//ASSERT(-1 <= diff && diff <= 1);
			//ASSERT(diff != 0);
			//ASSERT(diff > 0 ? child == 1 : child == 0);
#endif
			node = node->avl_child[child];
		}
#ifdef DEBUG
		diff = tree->avl_compar(new_data,
		    AVL_NODE2DATA(node, tree->avl_offset));
		//ASSERT(-1 <= diff && diff <= 1);
		//ASSERT(diff != 0);
		//ASSERT(diff > 0 ? child == 1 : child == 0);
#endif
	}
	//ASSERT(node->avl_child[child] == NULL);

	avl_insert(tree, new_data, AVL_MKINDEX(node, child));
}