Δουλεύω για την εφαρμογή ενός AVL δέντρου αναζήτησης. Μέχρι στιγμής έχω τελειώσει το τμήμα κωδικοποίησης και έχω αρχίσει τις δοκιμές του για σφάλματα. Ανακάλυψα ότι οι μέθοδοι περιστροφής του κόμβου μου ζητούσαν και για όνομα του Θεού, δεν μπορώ να καταλάβω ποιο είναι το πρόβλημα.
Ο αλγόριθμος λειτουργεί όπως θα έπρεπε σε χαρτί, αλλά όταν εκτελείται σε ένα μηχάνημα καλά ... διαρροές κόμβους του δέντρου.
Αυτή είναι η μέθοδος που χρησιμοποιείται για να περιστρέφει ένα κόμβο προς τα αριστερά: 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;
}
Στη μέθοδο εισαγωγής μου σχολίασε το AVL εξισορρόπηση μέρος και όχι Είμαι απλώς προσπαθούν να περιστρέψετε το πρόσφατα εισαχθεί κόμβο προς τα αριστερά. Το αποτέλεσμα για την εισαγωγή ακέραιους σε αύξουσα σειρά: το δέντρο μου περιέχει μόνο την αρχική ρίζα (πρώτος κόμβος εισάγεται) και όλοι οι άλλοι κόμβοι διαρρεύσει.
Οποιαδήποτε βοήθεια στον εντοπισμό του προβλήματος εκτιμάται ιδιαίτερα ως αρχίζω να τρελαίνομαι.
Για την ιστορία: αν δεν χρησιμοποιείτε περιστροφές το δέντρο δεν θα διαρρεύσει κόμβους και λειτουργεί ως ένα κανονικό ισορροπημένη δυαδικό δέντρο αναζήτησης (για εισαγωγή και αναζήτηση).
Επεξεργασία: Λόγω σχόλιο AJG85 του εγώ θα προσθέσω τις παρατηρήσεις:
Πρόσθεσα printf «ελέγχους» με τη μέθοδο destructor της avl_search_tree :: avl_tree_node που θα εκτυπώσετε την τιμή του κλειδιού (στην περίπτωσή μου 32 ακέραιοι bit) πριν καθαρισμού και, με τη μέθοδο ένθετο της avl_search_tree που θα εκτυπώσει το κλειδί μόλις εισαχθεί.
Στη συνέχεια, το entrypoint του προγράμματος θα χορηγήσει avl_search_tree στο σωρό και προσθέστε τα κλειδιά για να σε αύξουσα σειρά και στη συνέχεια να το διαγράψετε.
Με ενεργοποιημένο το AVL Εξισορρόπηση παίρνω το ακόλουθο αποτέλεσμα στο τερματικό:
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
Πράγμα που σημαίνει thatall εισαγωγές ήταν επιτυχής, αλλά μόνο η ρίζα έχει διαγραφεί.
Με το AVL εξισορρόπηση σε σχόλια λειτουργεί σαν ένα κανονικό δυαδικό δέντρο αναζήτησης. Η έξοδος τερματικό είναι:
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
Πράγμα που σημαίνει ότι όλα είναι σωστά καθαριστεί.
Τώρα ... πώς θα καταλήξει στο συμπέρασμα ότι οι μέθοδοι περιστροφής είναι τα θέματα; Υπό την σχολίασαν AVL εξισορρόπησης υπορουτίνα Ι προστίθεται μια γραμμή που περιστρέφεται κάθε πρόσφατα εισαχθεί κόμβο προς τα αριστερά. Το αποτέλεσμα? Το ίδιο όπως και αν η υπορουτίνα AVL Balancing έχει ενεργοποιηθεί.
Και όσον αφορά τη μέθοδο update_height (), δεν μεταβάλλει τη δομή του δέντρου με οποιονδήποτε τρόπο.
Ελπίζω ότι αυτό θα το αποσαφηνίσει.
Επεξεργασία 2:
Για να διευκρινιστούν κάποια περισσότερα πράγματα, αλλά είναι το πώς υλοποιείται η καταστροφέα avl_tree_node:
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 και _right_child είναι δείκτες σε avl_tree_node αντικείμενα που διατίθενται στο σωρό.
Επεξεργασία 3:
Χάρη στην 2η σχόλιο AGJ85 βρήκα το θέμα. Σε περιστροφή μεθόδους μου ξέχασα πως στην πραγματικότητα πρέπει να ενημερώσετε το δείκτη ρίζα του δέντρου με την νέα ρίζα, όταν η ρίζα μετατοπίστηκε.
Βασικά ρίζα του δέντρου ήταν πάντα δείχνουν προς την πρώτη εισαχθεί κόμβο και χωρίς ενημέρωση του δείκτη όταν χρειάζεται, περιστροφή μεθόδους μου θα διαρρεύσει ρίζα του νέου δέντρου που στην πραγματικότητα έχει ρυθμιστεί σωστά. :)
Σας ευχαριστούμε AGJ85!













