Я работаю на реализацию дерева поиска 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 «проверки» методу деструктор avl_search_tree :: avl_tree_node, который будет печатать ключевое значение (в моем случае 32-битных целых чисел) перед очисткой и к способу вставки в 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 Балансировка была включена.
А что касается методы 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!













