Эта проблема сложнее, чем кажется на первый взгляд.
Рассмотрим дерево из вашего первого примера:
2
1 3
Как вы сказали, есть два возможных порядка ввода: 2,1,3
и 2,3,1
. Правило такое: корень, потом дети в любом порядке.
Но это слишком просто. Чтобы увидеть всю сложность проблемы, вы должны расширить ее на другой уровень. Таким образом, ваш второй пример:
5
3 7
2 4 6 8
Обычно существует два способа построения этого дерева: сначала в ширину или в глубину. Чтобы сделать это в ширину, вы неоднократно применяете правило «сначала корень, затем потомки в любом порядке». Таким образом:
5,3,7,2,4,6,8
5,3,7,2,4,8,6
5,3,7,2,6,4,8
...
5,7,3,8,6,4,2
На каждом уровне есть (2 ^ k)! перестановок, где k — уровень. Таким образом, имеется 1 перестановка в корне, две перестановки на втором уровне (k == 1), 24 перестановки на следующем уровне и т. д.
Но выполнение этой широты в первую очередь не будет генерировать все возможные допустимые входные данные. Например, 5,3,2,4,7,6,8
вполне допустимо. Чтобы получить все допустимые входные данные, вы также должны включить построение в глубину. И тут все становится как-то интересно.
Вы можете сгенерировать предварительный обход дерева: 5,3,2,4,7,6,8
или обратный предварительный обход: 5,7,6,8,3,2,4
. Здесь действует правило root, а затем обход дочерних элементов в глубину в любом порядке.
Но это не покрывает странный случай 5,3,2,7,8,4,6
, который просто пропускает, но гарантирует, что родительский узел будет предоставлен перед любым из его дочерних элементов.
У меня нет полного решения, но я могу дать вам начало алгоритма. Рассмотрим случай случайной генерации действительной входной последовательности. Вы можете сделать это с помощью цикла:
nodes_array = create an array of nodes that can be selected
output_array = array of selected nodes
add root to nodes_array
while nodes_array is not empty
temp = randomly select node from nodes_array, and remove it
if temp.left != null
add temp.left to nodes_array
if temp.right != null
add temp.right to nodes_array
append temp to output_array
end while
Это всегда должно генерировать допустимый ввод, потому что дочерний узел никогда не добавляется в выходной массив, если его родитель уже не выбран.
Таким образом, проблема генерирования всех допустимых комбинаций становится проблемой изменения шага случайного выбора таким образом, чтобы на каждом уровне он генерировал все возможные перестановки nodes_array
. Генерация перестановок - решаемая задача. Однако применение этого рекурсивно требует некоторого размышления.
person
Jim Mischel
schedule
01.04.2014
1 2 3 4 5
допустимым шаблоном для дерева в вашем примере? Если нет, то почему? - person Bernhard Barker   schedule 31.03.2014123
недействителен, потому что он изменит древовидную структуру, но, поскольку вы не дали правил относительно того, как дерево генерируется из шаблона, ничто не мешает нарисованному вами дереву быть допустимым деревом для123
. Я предполагаю, что вы предполагаете, что шаблон представляет собой обход дерева по уровням (см. Википедия , но вам абсолютно необходимо явно указать это. - person Bernhard Barker   schedule 31.03.2014