Начните с облегчения своей работы.
Влево и вправо должны быть уникальными ptrs. Родитель голый ptr.
Получить влево / вправо возвращает голый ptr. Снижение влево / вправо возвращает уникальный родительский элемент ptr, и null в уникальном дереве ptr'd.
Набор занимает уникальный ptr.
Поворот функций принимает уникальный ptr, а возвращает уникальный ptr.
Люди, которые вызывают функции поворота, должны отрываться от родителя, вращать это дерево, а затем возвращать его в родительский.
BSTNode *k1 = k2->left;
k2->left = k1->right;
k1->right = k2;
k2 = k1;
это классический код только для чтения. У нас есть указатели и ссылки, летающие вокруг. Он настолько короткий, насколько это возможно, но это потому, что он был решен, а затем оптимизирован вручную. Это не дает образования, разве что как загадка.
Мы хотим перейти от:
a
b R
L c
до:
b
L a
c R
Итак, в псевдокоде:
up<Node> rot_left( up<Node> a ){
auto b=a->snip_left();
auto c=b->snip_right();
a->set_left(std::move(c));
b->set_right(std::move(a));
return b;
}
Я думаю, что это правильно. Для проверки напишите валидатор дерева и дампер. Утверждаю, что мы никогда не перезаписываем ветку, не являющуюся эмоциями Утверждают, что деревья действительны после и перед каждой операцией. Перед тем как сделать дерево похожим на дерево, бросьте его в дерево. Дамп дерево после. Подтвердите, что это выглядит правильно. Сравните то, что я описал, с вашими лекционными заметками и интернетом.
Theae шаги могут быть выполнены без переписывания вашего кода для использования уникальных ptrs; достаточно иметь методы snip / set / get, которые поддерживают инварианты.
Из-за этого переписывания я подозреваю, что проблема в том, что ваш код поворота неправильно поддерживает родительские ptrs. Триада snip / set / get сделает это за вас, если вы будете использовать ее осторожно; уникальный ptr, но должен отличать операции владения (snip / set) от операций наблюдения (get).