Які комбінації попередньої, після і після замовлення секвенціалізації є унікальними?


28

Ми знаємо, що після замовлення

post L(x)     => [x]
post N(x,l,r) => (post l) ++ (post r) ++ [x]

та попереднє замовлення

pre L(x)     => [x]
pre N(x,l,r) => [x] ++ (pre l) ++ (pre r)

і в порядку проходження респ. секвенціалізація.

in L(x)     => [x]
in N(x,l,r) => (in l) ++ [x] ++ (in r)

Легко помітити, що жодне дерево не описує однозначно, навіть якщо ми припускаємо попарно окремі клавіші / мітки.

Які комбінації трьох можна використовувати для цього, а які не можна?

Позитивні відповіді повинні включати (ефективний) алгоритм реконструкції дерева та доказ (ідею), чому він правильний. Негативні відповіді повинні містити зустрічні приклади, тобто різні дерева, які мають однакове представлення.

Відповіді:


16

По-перше, я припускаю, що всі елементи відрізняються. Жодна кількість послідовностей не збирається повідомити вам форму дерева з елементами [3,3,3,3,3]. Можна, звичайно, реконструювати деякі дерева з повторюваними елементами; Я не знаю, які хороші умови існують.

Продовжуючи негативні результати, ви не можете повністю відновити бінарне дерево з його послідовності попереднього замовлення та після замовлення. [1,2]попереднє замовлення, [2,1]після замовлення має бути 1в корені, але це 2може бути або ліва дитина, або права дитина. Якщо вас не хвилює ця неоднозначність, ви можете реконструювати дерево за допомогою наступного алгоритму:

  • Нехай - обхід попереднього замовлення, а - обхід після замовлення. У нас повинно бути , і це корінь дерева.[x1,,xn][yn,,y1]x1=y1
  • x2 - найменша ліва дитина кореня, а - найменша права дитина. Якщо , кореневий вузол не одинаковий; повторити курси на та щоб створити єдине піддерево.y2x2=y2[x2,,xn][yn,,y2]
  • В іншому випадку, нехай і є такими індексами, що і . - обхід попереднього замовлення лівого піддерева, , правого піддерева, і аналогічно для обходу після замовлення. У лівому піддереві є елементів, а в правому піддереві є елементів. Повторіть один раз для кожного піддерева. До речі, цей метод узагальнює дерева з довільним розгалуженням. За допомогою довільного розгалуження з’ясуйте розмір лівого піддерева і відріжте його елементи з обох списків, потім повторіть, щоб відрізати друге піддерево зліва тощо.ijx2=yiy2=xj[x2,,xj1][xj,,xn]j2=ni+1i2=nj+1
    j2

Як зазначалося, час роботи - це з найгіршим випадком (у випадку з двома дітьми ми шукаємо кожен список лінійно). Ви можете перетворити це на якщо попередньо обробити списки для побудови кінцевої структури карти від значень елементів до позицій у вхідних списках . Також використовуйте масив або кінцеву карту, щоб перейти від індексів до значень; дотримуйтесь глобальних індексів, щоб рекурсивні дзвінки отримували цілі карти і приймали діапазон як аргумент, щоб знати, на що діяти.O(n2)Θ(n2)nO(nlg(n))nlg(n)

За допомогою обходу попереднього замовлення та обходу замовлення ви можете відновити дерево таким чином:[ z 1 , , z n ][x1,,xn][z1,,zn]

  • Корінь - голова обходу попереднього замовлення .x1
  • Нехай - індекс такий, що . Тоді - це порядок обходу лівої дитини, а - порядок обходу правильної дитини. За кількістю елементів, - це обхід попереднього замовлення лівої дитини та що належить дитині. Повторіть, щоб побудувати лівий і правий підтрубки.z k = x 1kzk=x1[ z k + 1 , , z n ] [ x 2 , , x k ] [ x k + 1 , , x n ][z1,,zk1][zk+1,,zn][x2,,xk][xk+1,,xn]

Знову ж таки, цей алгоритм є як зазначено, і його можна виконати в якщо список попередньо обробляється в кінцевій карті від значень до позицій.O ( nO(n2)O(nlg(n))

Після замовлення плюс замовлення, звичайно, симетричний.


Чи є друкарська помилка: "[1,2] попереднє замовлення, [1,2] післязамовне замовлення повинно мати 1 в корені, але 2 може бути або лівою дитиною, або правою дитиною." Порядок публікації такого дерево буде [2,1], а не [1,2], 2 чи ліва чи права дитина. Крім того, ви маєте на увазі, якщо подано і попереднє замовлення, і після порядок, ми не можемо реконструювати дерево, чи ви маєте на увазі, якщо нам дали лише одне з них, то ми не зможемо реконструювати дерево?
CEGRD

@CEGRD Дійсно, порядок був помилковим. Приклад показує, що ви не можете повністю реконструювати дерево в цьому випадку: ви не можете знати 2, це дитина ліва чи права дитина. Це відповідає випадку "єдиного піддерева" алгоритму відновлення.
Жил "ТАК - перестань бути злим"

як це змінюється, якщо ми знаємо, що це бінарне дерево пошуку? для простого випадку у вашому прикладі ([1,2] попереднє замовлення, [2,1] після замовлення) ми змогли б визначити, що корінь дорівнює 1, а 2 - правильна дитина (адже 2 більше, ніж 1) ... правда?
fersarr
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.