Jsem pracující na realizaci AVL vyhledávací strom. Zatím jsem dokončil kódovací část a já jsem začal testovat to pro chyby. Zjistil jsem, že moje uzel metody rotace jsou odposlouchávány a proboha nemohu pochopit, v čem je problém.
Algoritmus pracuje tak, jak má na papíře, ale když je vykonáván na stroji je dobře ... nevrací uzly stromu.
Tato metoda používá k otočení uzlu doleva: http://pastebin.com/mPHj29Af
bool avl_search_tree::avl_tree_node::rotate_left()
{
if (_right_child != NULL) {
avl_tree_node *new_root = _right_child;
if (_parent != NULL) {
if (_parent->_left_child == this) {
_parent->_left_child = new_root;
} else {
_parent->_right_child = new_root;
}
}
new_root->_parent = _parent;
_parent = new_root;
_right_child = new_root->_left_child;
new_root->_left_child = this;
if (_right_child != NULL) {
_right_child->_parent = this;
}
//update heights
update_height();
new_root->update_height();
return true;
}
return false;
}
V mém způsobu vkládání I komentoval AVL vyrovnávání část a místo toho jsem prostě se snaží otočit nově vložený uzel doleva. Výsledek pro vkládání celých čísel ve vzestupném pořadí: můj strom obsahuje pouze prvotní kořen (první uzel vložen) a všechny ostatní uzly jsou unikly.
Jakákoli pomoc při identifikaci problému je vysoce ceněn jako já začínám zbláznit.
Pro připomenutí: v případě, že nepoužívám žádné střídání strom nebude úniku uzlů a funguje jako normální nevyváženého binárního vyhledávacího stromu (pro vkládání a vyhledávání).
Edit: Vzhledem k AJG85 komentáři Přidám pozorování:
Přidal jsem printf ‚kontroly‘ metody destruktor avl_search_tree :: avl_tree_node který vytiskne hodnotu klíče (v mém případě 32 bitová celá čísla) před vyčištění a do vložky způsobu avl_search_tree který bude tisknout tlačítko právě vložili.
Pak v EntryPoint programu I přidělit avl_search_tree na haldě a přidat klíče k ní ve vzestupném pořadí a poté jej odstraňte.
Se zapnutým AVL Vyrovnávání se mi zobrazí následující výstup v terminálu:
bool avl_search_tree::insert(const int&) : 1
bool avl_search_tree::insert(const int&) : 2
bool avl_search_tree::insert(const int&) : 3
bool avl_search_tree::insert(const int&) : 4
bool avl_search_tree::insert(const int&) : 5
bool avl_search_tree::insert(const int&) : 6
bool avl_search_tree::insert(const int&) : 7
bool avl_search_tree::insert(const int&) : 8
avl_search_tree::avl_tree_node::~avl_tree_node() : 1
Což znamená, že thatall inzercí byly úspěšné, ale jen kořen byl odstraněn.
S AVL Vyvažování vyjádřil se, že to funguje jako normální binární vyhledávací strom. Terminál výstup je:
bool avl_search_tree::insert(const int&) : 1
bool avl_search_tree::insert(const int&) : 2
bool avl_search_tree::insert(const int&) : 3
bool avl_search_tree::insert(const int&) : 4
bool avl_search_tree::insert(const int&) : 5
bool avl_search_tree::insert(const int&) : 6
bool avl_search_tree::insert(const int&) : 7
bool avl_search_tree::insert(const int&) : 8
avl_search_tree::avl_tree_node::~avl_tree_node() : 1
avl_search_tree::avl_tree_node::~avl_tree_node() : 2
avl_search_tree::avl_tree_node::~avl_tree_node() : 3
avl_search_tree::avl_tree_node::~avl_tree_node() : 4
avl_search_tree::avl_tree_node::~avl_tree_node() : 5
avl_search_tree::avl_tree_node::~avl_tree_node() : 6
avl_search_tree::avl_tree_node::~avl_tree_node() : 7
avl_search_tree::avl_tree_node::~avl_tree_node() : 8
Což znamená, že vše je řádně vyčištěna.
A teď ... jak jsem dospěl k závěru, že metody rotace jsou problémy? Podle komentovaného vyváženosti AVL podprogram jsem přidal řádek, který se otáčí každý nově vložený uzel doleva. Výsledek? Stejně jako v případě, že AVL Balancing podprogram byl povolen.
A pokud jde o metodu update_height (), to nic nemění strukturu stromu v žádném případě.
Doufám, že to bude to objasnit.
Edit 2:
Vyjasnit některé další věci, jeho je, jak je implementována avl_tree_node destruktor:
avl_search_tree::avl_tree_node::~avl_tree_node()
{
printf(%s : %d\n, __PRETTY_FUNCTION__, *_key);
if (_left_child != NULL) {
delete _left_child;
}
if (_right_child != NULL) {
delete _right_child;
}
if (_key != NULL) {
delete _key;
}
}
_left_child a _right_child jsou ukazatele na avl_tree_node objekty na haldě.
Edit 3:
Díky AGJ85 je 2. komentáři jsem našel problém. V mých otáčet metod jsem zapomněla, že jsem vlastně muset aktualizovat kořenový ukazatel stromový do nové kořeni, když byl kořen posunut.
V podstatě kořen stromu byla vždy ukazoval na první vloženou uzlu a bez aktualizace ukazatel v případě potřeby, moji Otočení metody by unikat kořen nové větve, která byla ve skutečnosti nakonfigurován správně. :)
Děkuji AGJ85!













