@@ -20,6 +20,8 @@ namespace lol | |||
template<typename K, typename V> | |||
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; | |||
@@ -0,0 +1,66 @@ | |||
// | |||
// Lol Engine | |||
// | |||
// Copyright: (c) 2010-2014 Sam Hocevar <sam@hocevar.net> | |||
// (c) 2013-2014 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||
// (c) 2013-2014 Guillaume Bittoun <guillaume.bittoun@gmail.com> | |||
// 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 <lol/engine-internal.h> | |||
#include <lolunit.h> | |||
namespace lol | |||
{ | |||
class test_tree : public avl_tree<int, int> | |||
{ | |||
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); | |||
} | |||
}; | |||
} |