AK: Fix RedBlackTree::find_smallest_not_below_iterator

Before this was incorrectly assuming that if the current node `n` was at
least the key and the left child of `n` was below the key that `n` was
always correct.
However, the right child(ren) of the left child of `n` could still be
at least the key.

Also added some tests which produced the wrong results before this.
This commit is contained in:
davidot 2022-02-10 10:36:09 +01:00 committed by Linus Groh
parent 41dae9b3c7
commit 2bddf157b1
Notes: sideshowbarker 2024-07-17 19:03:23 +09:00
2 changed files with 49 additions and 4 deletions

View file

@ -133,16 +133,19 @@ protected:
static Node* find_smallest_not_below(Node* node, K key) static Node* find_smallest_not_below(Node* node, K key)
{ {
Node* candidate = nullptr;
while (node) { while (node) {
if (node->key >= key && (!node->left_child || node->left_child->key < key)) if (node->key == key)
return node; return node;
if (node->key <= key) if (node->key <= key) {
node = node->right_child; node = node->right_child;
else } else {
candidate = node;
node = node->left_child; node = node->left_child;
} }
return node; }
return candidate;
} }
void insert(Node* node) void insert(Node* node)

View file

@ -86,3 +86,45 @@ TEST_CASE(clear)
test.clear(); test.clear();
EXPECT_EQ(test.size(), 0u); EXPECT_EQ(test.size(), 0u);
} }
TEST_CASE(find_smallest_not_below_iterator)
{
RedBlackTree<size_t, size_t> test;
for (size_t i = 0; i < 8; i++) {
auto above_all = test.find_smallest_not_below_iterator(i);
EXPECT(above_all.is_end());
test.insert(i, i);
auto only_just_added_i_is_not_below = test.find_smallest_not_below_iterator(i);
EXPECT(!only_just_added_i_is_not_below.is_end());
EXPECT_EQ(only_just_added_i_is_not_below.key(), i);
}
{
auto smallest_not_below_two = test.find_smallest_not_below_iterator(2);
EXPECT(!smallest_not_below_two.is_end());
EXPECT_EQ(smallest_not_below_two.key(), 2u);
}
test.remove(2);
{
auto smallest_not_below_two_without_two = test.find_smallest_not_below_iterator(2);
EXPECT(!smallest_not_below_two_without_two.is_end());
EXPECT_EQ(smallest_not_below_two_without_two.key(), 3u);
}
{
auto smallest_not_below_one = test.find_smallest_not_below_iterator(1);
EXPECT(!smallest_not_below_one.is_end());
EXPECT_EQ(smallest_not_below_one.key(), 1u);
}
{
auto smallest_not_below_three = test.find_smallest_not_below_iterator(3);
EXPECT(!smallest_not_below_three.is_end());
EXPECT_EQ(smallest_not_below_three.key(), 3u);
}
}