Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions include/libbase/avltree.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,14 @@ bs_avltree_node_t *bs_avltree_node_next(bs_avltree_t *tree_ptr,
bs_avltree_node_t *bs_avltree_node_prev(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr);

/** Deletes the node. Must be part of tree_ptr. */
void bs_avltree_node_delete(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr);

/** @return whether |tree_ptr| contains |node_ptr. */
bool bs_avltree_contains_node(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr);

/**
* Helper: Comparator to compare two pointers.
*
Expand Down
32 changes: 28 additions & 4 deletions src/avltree.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,6 @@ static size_t bs_avltree_node_height(bs_avltree_t *tree_ptr,
static void bs_avltree_node_exchange(bs_avltree_t *tree_ptr,
bs_avltree_node_t *old_node_ptr,
bs_avltree_node_t *new_node_ptr);
static void bs_avltree_node_delete(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr);

static bool bs_avltree_rot_right(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr);
Expand Down Expand Up @@ -294,6 +292,15 @@ bs_avltree_node_t *bs_avltree_node_prev(__UNUSED__ bs_avltree_t *tree_ptr,
return node_ptr->parent_ptr;
}

/* ------------------------------------------------------------------------- */
bool bs_avltree_contains_node(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr)
{
if (NULL == node_ptr) return false;
while (NULL != node_ptr->parent_ptr) node_ptr = node_ptr->parent_ptr;
return tree_ptr->root_ptr == node_ptr;
}

/* ------------------------------------------------------------------------- */
int bs_avltree_cmp_ptr(const void *node_key_ptr,
const void *key_ptr)
Expand Down Expand Up @@ -511,6 +518,8 @@ void bs_avltree_node_exchange(bs_avltree_t *tree_ptr,
void bs_avltree_node_delete(bs_avltree_t *tree_ptr,
bs_avltree_node_t *node_ptr)
{
BS_ASSERT(bs_avltree_contains_node(tree_ptr, node_ptr));

bs_avltree_node_t *next_larger_node_ptr = NULL;

if ((NULL != node_ptr->left_ptr) && (NULL != node_ptr->right_ptr)) {
Expand Down Expand Up @@ -925,7 +934,14 @@ void bs_avltree_test_random(bs_test_t *test_ptr)

BS_TEST_VERIFY_NEQ(test_ptr, node_ptr, NULL);
if (NULL != node_ptr) {
BS_TEST_VERIFY_TRUE(
test_ptr,
bs_avltree_contains_node(tree_ptr, &node_ptr->node));
BS_TEST_VERIFY_EQ(test_ptr, node_ptr->value, value);
} else {
BS_TEST_VERIFY_FALSE(
test_ptr,
bs_avltree_contains_node(tree_ptr, &node_ptr->node));
}
}

Expand Down Expand Up @@ -960,8 +976,16 @@ void bs_avltree_test_random(bs_test_t *test_ptr)
for (value_idx = 0; value_idx < BS_AVLTREE_TEST_VALUES; value_idx++) {
value = random_values[value_idx];

node_ptr = (bs_avltree_test_node_t*)
bs_avltree_delete(tree_ptr, &value);
if (value & 0x1) {
node_ptr = (bs_avltree_test_node_t*)
bs_avltree_delete(tree_ptr, &value);
} else {
node_ptr = (bs_avltree_test_node_t*)
bs_avltree_lookup(tree_ptr, &value);
if (NULL != node_ptr) {
bs_avltree_node_delete(tree_ptr, &node_ptr->node);
}
}
if (node_ptr != NULL) {
BS_TEST_VERIFY_EQ(test_ptr, node_ptr->value, value);
bs_avltree_test_node_destroy(&node_ptr->node);
Expand Down
Loading