Обход дерева для замены двух узлов - PullRequest
0 голосов
/ 28 октября 2011

Я только что столкнулся с этой проблемой и задавался вопросом, смогу ли я найти правильное решение.Проблема заключается в замене двух узлов двоичного дерева не только по значению, но и по узлу.Таким образом, это означает, что мы должны изменить правое и левое значения.

BST

Итак, допустим, что у нас есть двоичное дерево, похожее на изображение выше.Сначала я подумал об обходе узлов по порядку, чтобы я мог сгладить дерево, а затем просто поменять местами элементы, а затем восстановить дерево из списка подкачки.Таким образом, буквально решение выглядит примерно так:

. Для вышеупомянутого дерева обход по порядку генерирует такой список:

1,3,4,6,7,8,10,13,14.

Теперь я поменяю местами 8 и 13.

=> 1,3,4,6,7,13,10,8,14

Нопроблема здесь в том, что, поскольку я теперь сплющил дерево, когда я пытаюсь восстановить, я не могу это сделать, потому что я не знаю положение отдельных узлов, например, является ли конкретный узел левым подчиненным или если он является корнем,Таким образом, в буквальном смысле дерево не может быть восстановлено так же, как это было изначально с переставленными узлами.

Теперь вопрос заключается в том, могу ли я изменить свой алгоритм обхода, чтобы он содержал информацию о положении каждого из узлов, чтобы при замене элементов и восстановлении я получал одно и то же двоичное дерево с заменой нужных узлов?Можем ли мы сохранить состояние / положение отдельных узлов при прохождении по порядку?

PS.Я признаю, что выполнение пост-заказа приведет к тому, что мой список с первым и последним узлами будет заменен, но два узла, которые нужно поменять местами, не обязательно должны быть в корне и в самом правом элементе, это могут быть любые два.

1 Ответ

0 голосов
/ 28 октября 2011

В вашем вопросе немного неясностей.Дерево в вашем примере в BST (хотя BST также является двоичным деревом) и окончательный ответ может нарушить свойство BST.Я полагаю, вот какой ответ должен быть.Поправьте меня, если я ошибаюсь.

Что касается ответа, есть 2 решения.

Один, о котором я могу думать, говоря в терминах обхода и сплющивания, вы не можете повторнопостроить дерево с помощью всего одного обхода.Вам нужно 2 обхода, чтобы построить дерево.Это может быть один из следующих пунктов:

  1. Предзаказ и В порядке
  2. Почтовый заказ и В порядке
  3. Уровень заказа и В порядке

Так же сделайте обмен на любом из 2 обходов и восстановите.Это должно дать ответ.

Второе решение - намного лучшее и эффективное решение, потому что Time Comp - O (n).В этом методе выполните обход по всему дереву и получите указатели ссылок на 2 узла-кандидата.Получив ссылки, используйте переменную temp для обмена информацией. Этот метод сложен, но эффективен с точки зрения пространства и времени, чем предыдущий подход.


Надеюсь, это не вопрос HW, если такпожалуйста, отметьте его!

Например:

            4
        2       6
      1   3   5   7

Порядок обхода для этого дерева выглядит следующим образом: Pre: 4 2 1 3 6 5 7 Inorder: 1 2 3 4 5 6 7

Теперь вы знаете, что 4 является корнем этого дерева (поскольку корень печатается как первый элемент для Preorder).На основе 4 теперь разделите обходы.

Теперь левое поддерево становится Pre: 2 1 3;Inorder: 1 2 3

и правое поддерево становится Pre: 6 5 7;Inorder: 5 6 7

Продолжайте делать это рекурсивно, вот и ответ!

...