Это отвечает на вопрос, как изначально сформулированный, то есть после идентификация деревьев в смысле одной и той же структуры и элементов.
Сравнение последовательности (или любой другой) последовательности не будет работать: разные деревья имеют одинаковый обход. Например, деревья
[source]
имеют то же самое в порядка обхода a,b,c,d,e
. Вы можете использовать two (different) traversals и проверить, одинаковы ли они соответственно.
Классическое решение, однако, является рекурсивный алгоритм:
equal Leaf(x) Leaf(y) => x == y
| equal Node(x,l1,r1) Node(y,l2,r2) => x == y && equal(l1,l2) && equal(r1,r2)
| equal _ _ => false;
Он выполняет обход дерева на обоих одновременно деревьев и занимает много времени Q (п), п максимум соответствующего числа узлов.
Что касается обновленного вопроса, то проверка обходных порядков для элементарного равенства достаточно. Обратите внимание, что по определению обход BST-порядка в порядке сортированного списка сохраненных элементов, поэтому этот подход является правильным. В рекурсивной форме, это алгоритм:
inorder Leaf(x) = [x]
| inorder Node(x,l,r) = (inorder l) ++ [x] ++ (inorder r);
equal [] [] = true
| equal x1::r1 x2::r2 = x1 == x2 && (equal r1 r2)
| equal _ _ = false;
sameElems t1 t2 = let
e1 = inorder t1
e2 = inorder t2
in
equal e1 e2
end;
Если список конкатенация может быть сделана во время O (1), это работает во время Q (п) и пространство Q (п); итерационные решения, безусловно, такие же хорошие, и, вероятно, лучшие константы.
Если вы хотите выполнить эту проверку в o (n) времени, вы даже не можете смотреть на каждый элемент. В общем, оба дерева содержат попарно разные элементы, поэтому вы не можете использовать какие-либо диапазоны, поэтому для каждой общей проверки равенства элемента требуется время Ω (n) (предполагайте более быстрый алгоритм и постройте два дерева, для которых он не выполняется).
Пространство может быть выполнено лучше, чем O (n). Если вы реализуете в порядке cleverly ¹, вам потребуется только O (1) дополнительное пространство (указатель на текущие элементы, некоторые управляющие счетчики/флаги).
- Обратите внимание, что этот алгоритм разрушает дерево временно, поэтому он не подходит в параллельных установках.
Что вы подразумеваете под «двумя деревьями одинаковыми»? Означает ли это, что (1) они содержат один и тот же набор элементов, (2) формы деревьев одинаковы, но они могут содержать разные элементы, (3) оба элемента и формы одинаковы или (4) что-то еще? Мне кажется, что люди неявно принимают разные интерпретации и дают ответы на разные вопросы. –
«два дерева одинаковы» означает, что они содержат один и тот же набор элементов. –
Пожалуйста, отредактируйте этот вопрос. Как вы можете видеть из всех этих разных интерпретаций, «деревья одинаковы» неоднозначны. –