diff --git a/src/lol/algorithm/avl_tree.h b/src/lol/algorithm/avl_tree.h index 8bf47848..e162d0f5 100644 --- a/src/lol/algorithm/avl_tree.h +++ b/src/lol/algorithm/avl_tree.h @@ -20,6 +20,8 @@ namespace lol template class avl_tree { +public: + avl_tree() : m_root(0) { @@ -35,9 +37,9 @@ class avl_tree if (created) { - this->m_root->path_update_balance(created); + this->m_root->path_update_balance(key); - tree_node * new_root = this->m_root->path_rebalance(created); + tree_node * new_root = this->m_root->path_rebalance(key); if (new_root) this->m_root = new_root; } @@ -48,10 +50,12 @@ class avl_tree return true; } -private: +protected: class tree_node { + public: + tree_node(K key, V value) : m_key(key), m_value(value), @@ -100,7 +104,7 @@ private: { if (key < this->m_key) { - tree_node * node = this->m_lo->path_rebalance(); + tree_node * node = this->m_lo->path_rebalance(key); if (node) { this->m_lo = node; @@ -109,7 +113,7 @@ private: } else if (this->m_key < key) { - tree_node * node = this->m_hi->path_rebalance(); + tree_node * node = this->m_hi->path_rebalance(key); if (node) { this->m_hi = node; @@ -117,16 +121,16 @@ private: } } - if (this->m_stairs_lo - this->m_stairs_hi == 2) + if (this->get_balance() == 2) { - return this->rotate(); + return this->rotate(CW); } - else if (this->m_stairs_lo - this->m_stairs_hi == -2) + else if (this->get_balance() == -2) { - return this->rotate(); + return this->rotate(CCW); } else - assert(lol::abs(this->m_stairs_lo - this->m_stairs_hi) < 3); + ASSERT(lol::abs(this->m_stairs_lo - this->m_stairs_hi) < 3); } enum Rotation { CW = 0, CCW = 1 }; @@ -169,7 +173,12 @@ private: this->m_stairs_hi = this->m_hi ? this->m_hi->m_stairs_lo + this->m_lo->m_stairs_hi : 0; } - private: + int get_balance() + { + return this->m_stairs_lo - this->m_stairs_hi; + } + + protected: K m_key; V m_value; diff --git a/src/t/algorithm/avl_tree.cpp b/src/t/algorithm/avl_tree.cpp new file mode 100644 index 00000000..4c6ce83e --- /dev/null +++ b/src/t/algorithm/avl_tree.cpp @@ -0,0 +1,66 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2014 Sam Hocevar +// (c) 2013-2014 Benjamin "Touky" Huet +// (c) 2013-2014 Guillaume Bittoun +// This program is free software; you can redistribute it and/or +// modify it under the terms of the Do What The Fuck You Want To +// Public License, Version 2, as published by Sam Hocevar. See +// http://www.wtfpl.net/ for more details. +// + +#include + +#include + +namespace lol +{ + +class test_tree : public avl_tree +{ +public: + + int get_root_balance() + { + return this->m_root->get_balance(); + } +}; + +lolunit_declare_fixture(AvlTreeTest) +{ + void SetUp() {} + + void TearDown() {} + + lolunit_declare_test(AvlTreeInsert) + { + test_tree tree; + + lolunit_assert_equal(tree.insert(1, 1), true); + lolunit_assert_equal(tree.insert(2, 3), true); + lolunit_assert_equal(tree.insert(2, 0), false); + } + + lolunit_declare_test(AvlTreeBalanceCheck) + { + test_tree tree; + + lolunit_assert_equal(tree.insert(1, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 0); + + lolunit_assert_equal(tree.insert(2, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 1); + + lolunit_assert_equal(tree.insert(3, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 0); + + lolunit_assert_equal(tree.insert(0, 1), true); + lolunit_assert_equal(tree.get_root_balance(), -1); + + lolunit_assert_equal(tree.insert(-1, 1), true); + lolunit_assert_equal(tree.get_root_balance(), 0); + } +}; + +}