Sto lavorando per l'attuazione di una ricerca albero AVL. Finora ho finito la parte di codifica e ho cominciato a testarlo per i bug. Ho scoperto che i miei nodi metodi di rotazione vengono ostacolate e per l'amor di Dio, non riesco a capire qual è il problema.
L'algoritmo funziona come dovrebbe sulla carta, ma quando eseguito su una macchina bene ... perdite nodi dell'albero.
Questo è il metodo utilizzato per ruotare un nodo a fianco: 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;
}
Nel mio metodo di inserimento ho commentato l'AVL bilanciamento parte e invece sto solo cercando di ruotare il nodo appena inserito a sinistra. Il risultato per l'inserimento interi in ordine crescente: il mio albero ha solo la radice iniziale (primo nodo inserita) e tutti gli altri nodi si perdono.
Qualsiasi aiuto per identificare il problema è molto apprezzato come sto cominciando a impazzire.
Per la cronaca: se io non uso alcun rotazioni l'albero non colerà nodi e funziona come un normale sbilanciato albero binario di ricerca (per l'inserimento e ricerca).
Edit: Grazie al commento di AJG85 io aggiungo le osservazioni:
Ho aggiunto printf 'controlli' al metodo distruttore di avl_search_tree :: avl_tree_node che stamperà il valore della chiave (nel mio caso 32 numeri interi bit) prima di pulizia e, al metodo di inserimento del avl_search_tree che verrà stampata la chiave appena inserito.
Poi nel entrypoint del programma ho allocare un avl_search_tree sul mucchio e aggiungi le chiavi ad esso in ordine crescente e quindi eliminarlo.
Con AVL Balancing abilitato ottengo il seguente output nel terminale:
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
Il che significa thatall inserimenti hanno avuto successo, ma solo la radice è stato eliminato.
Con l'AVL Bilanciamento commentata funziona come un normale albero binario di ricerca. Il terminale di uscita è:
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
Il che significa che tutto sia ben ripulito.
Ora ... Come sono arrivato alla conclusione che i metodi di rotazione sono i problemi? Sotto la subroutine bilanciamento AVL commentato ho aggiunto una linea che ruota ogni nodo inserito a fianco. Il risultato? Lo stesso come se la subroutine AVL Balancing è stato attivato.
E per quanto riguarda il metodo update_height (), Esso non altera la struttura del albero in alcun modo.
Spero che questo permetterà di chiarire esso.
Edit 2:
Per chiarire alcune cose, la sua è come il distruttore avl_tree_node viene implementato:
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 e _right_child sono puntatori a avl_tree_node oggetti allocati sul mucchio.
Edit 3:
Grazie al 2 commento di AGJ85 ho trovato il problema. Nei miei metodi di rotazione ho dimenticato che io in realtà devo aggiornare puntatore radice dell'albero alla nuova radice ogni volta che la radice è stata spostata.
Fondamentalmente radice dell'albero era sempre rivolto al primo nodo inserito e senza aggiornare il puntatore quando necessario, miei metodi ruotare avrebbero perdite radice del nuovo albero che è stato effettivamente configurato destra. :)
Grazie AGJ85!













