diff --git a/src/lol/algorithm/avl_tree.h b/src/lol/algorithm/avl_tree.h index 463f1552..3d1d23e2 100644 --- a/src/lol/algorithm/avl_tree.h +++ b/src/lol/algorithm/avl_tree.h @@ -55,6 +55,26 @@ public: return true; } + bool erase(K const & key) + { + if (this->m_root) + { + tree_node * parent = this->m_root->get_parent(key); + + if (parent) + { + parent->delete_child(key); + this->m_root->update_balance(parent); + } + else if (this->m_root->get_key() == key) + { + // TODO + } + } + + return false; + } + protected: class tree_node @@ -249,6 +269,90 @@ protected: this->m_stairs[1] = this->m_child[1] ? lol::max(this->m_child[1]->m_stairs[0], this->m_child[1]->m_stairs[1]) + 1 : 0; } + bool is_equal(K const & key) + { + return !(key < this->m_key) && !(this->m_key < key); + } + + /* Retrieve the parent of an inserted key. + * Do not call "get_parent" if key is not already present in the tree. */ + tree_node * get_parent(K const & key) + { + if (key < this->m_key) + { + if (this->m_child[0]->is_equal(key)) + return this; + else + return this->m_child[0]->get_parent(key); + } + else if (this->m_key < key) + { + if (this->m_child[1]->is_equal(key)) + return this; + else + return this->m_child[1]->get_parent(key); + } + else + ASSERT(false); // Something went really really bad + } + + void delete_child(tree_node * parent, K const & key) + { + if (key < this->m_key) + { + tree_node * child = this->m_child[0]; + + if (this->m_child[0]->get_balance() == -1) + { + //TODO + } + else + { + // TODO + } + + child->m_child[0] = nullptr; + child->m_child[1] = nullptr; + delete child; + } + else if (this->m_key < key) + { + // TODO + } + else + ASSERT(false) // Do not delete the "this" node here + } + + tree_node * get_previous() + { + tree_node * previous = this->m_child[0]; + + if (previous) + { + while (previous->m_child[1]) + { + previous = previous->m_child[1]; + } + } + + return previous; + } + + tree_node * get_next() + { + tree_node * next = this->m_child[1]; + + if (next) + { + while (next->m_child[0]) + { + next = next->m_child[0]; + } + } + + return next; + } + int get_balance() { return this->m_stairs[1] - this->m_stairs[0]; diff --git a/src/t/algorithm/avl_tree.cpp b/src/t/algorithm/avl_tree.cpp index 1a674351..098bcceb 100644 --- a/src/t/algorithm/avl_tree.cpp +++ b/src/t/algorithm/avl_tree.cpp @@ -46,23 +46,32 @@ lolunit_declare_fixture(AvlTreeTest) { test_tree tree; - lolunit_assert_equal(tree.insert(1, 1), true); + lolunit_assert_equal(tree.insert(10, 1), true); lolunit_assert_equal(tree.get_root_balance(), 0); - lolunit_assert_equal(tree.insert(2, 1), true); + lolunit_assert_equal(tree.insert(20, 1), true); lolunit_assert_equal(tree.get_root_balance(), 1); - lolunit_assert_equal(tree.insert(3, 1), true); + lolunit_assert_equal(tree.insert(30, 1), true); lolunit_assert_equal(tree.get_root_balance(), 0); - lolunit_assert_equal(tree.insert(0, 1), true); + lolunit_assert_equal(tree.insert(00, 1), true); lolunit_assert_equal(tree.get_root_balance(), -1); - lolunit_assert_equal(tree.insert(-1, 1), true); + lolunit_assert_equal(tree.insert(-10, 1), true); lolunit_assert_equal(tree.get_root_balance(), -1); - lolunit_assert_equal(tree.insert(-2, 1), true); + lolunit_assert_equal(tree.insert(-20, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 0); + + lolunit_assert_equal(tree.insert(-20, 1), false); lolunit_assert_equal(tree.get_root_balance(), 0); + + lolunit_assert_equal(tree.insert(11, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 1); + + lolunit_assert_equal(tree.insert(13, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 1); } };