Я работаю над реализацией Splay Tree. Вставка работает отлично, но когда я пытаюсь развернуть вставленный узел зигзагообразно или зигзагообразно, я всегда получаю ошибку сегментации. Вращение вправо-влево, используемое, когда узел, который будет развернут, не имеет прародителя, работает отлично.
Вот код для вращения вправо-вправо зигзаг. Если я, например,
insert("z", 1);
insert("j", 1);
insert("p", 1);
zigZigRotate(root.get_left().get_left());
Я получаю бесконечный цикл J и P. Первый параметр вставки — это ключ, второй — ранг (для обхода по порядку).
Итак, в предыдущем примере, перед расширением, дерево будет выглядеть так:
Z
J
п
Поскольку z вставляется в положение 1, то j в положение 1, перемещается z в положение 2 и т. Д.
Вот зиг-зиг-код, который я имею для вращения вправо-вправо.
if (n == n->get_parent()->get_left())
{
if (n->get_right() != nullptr)
{
n->get_right()->set_parent(n->get_parent());
}
if (n->get_parent()->get_right() != nullptr)
{
n->get_parent()->get_right()->set_parent(n->get_parent()>get_parent());
}
n->get_parent()->get_parent()->set_parent(n->get_parent());
n->get_parent()->set_parent(n);
n->get_parent()->get_parent()->set_left(n->get_parent()->get_right());
n->get_parent()->set_right(n->get_parent()->get_parent());
n->get_parent()->set_left(n->get_right());
n->set_right(n->get_parent());
n->set_parent(n->get_parent()->get_parent()->get_parent());
}
Я проследил это, и кажется, что он должен вращаться правильно для меня. Нет места, где должен происходить бесконечный цикл. Но поскольку это так, я бы предположил, что j и p связаны друг с другом каким-то образом, каким они не должны быть. Например, у j есть p как его левый потомок, но по некоторым причинам у p есть j как один из его потомков.
Похоже, что порядок операций для всех этих изменений ссылок неправильный, или вам нужно сохранить некоторые из этих ссылок в локальных переменных перед внесением изменений. Работа через это на бумаге.
n->get_parent()->set_parent(n);
изменения строки n
прародитель. После этого звонки на n->get_parent()->get_parent()
собираемся вернуться n
, Это может вызывать петли в вашем дереве.
(Я предполагаю, что n->get_parent()>get_parent()
это тип, с ->
предназначено вместо сравнения.)
Других решений пока нет …