Один из способов решения этой проблемы состоит в том, чтобы заметить, что дерево является симметричным, если оно является его собственным отражением, где отражение дерева определяется рекурсивно:
- Отражение пустого дерева само по себе.
- Отражение дерева с корнем r и дочерних элементов c1, c2, ..., cn - это дерево с корнем r, а дочерние элементы отражают (cn), ..., отражают (c2), отражают (c1).
Затем вы можете решить эту проблему, вычислив отражение дерева и проверив, равно ли оно исходному дереву. Это снова может быть сделано рекурсивно:
- Пустое дерево равно только себе.
- Дерево с корнем r и дочерними элементами c1, c2, ..., cn равно другому дереву, если другое дерево непустое, имеет корень r, имеет n дочерних элементов и имеет дочерние элементы, равные c1,. .., сп в этом порядке.
Конечно, это немного неэффективно, потому что перед сравнением создается полная копия дерева. Использование памяти составляет O (n + d), где n - количество узлов в дереве (для хранения копии), а d - высота дерева (для хранения кадров стека в проверке рекурсии на равенство). Так как d = O (n), это использует O (n) памяти. Однако он выполняется за время O (n), поскольку каждая фаза посещает каждый узел ровно один раз.
Более эффективный способ сделать это - использовать следующую рекурсивную формулировку:
1. The empty tree is symmetric.
2. A tree with n children is symmetric if the first and last children are mirrors, the second and penultimate children are mirrors, etc.
Затем вы можете определить два дерева, которые будут зеркалами, следующим образом:
- Пустое дерево - только зеркало самого себя.
- Дерево с корнем r и дочерними элементами c1, c2, ..., cn является зеркалом дерева с корнем t и дочерними элементами d1, d2, ..., dn, если r = t, c1 является зеркалом dn с2 - зеркало дн-1 и т. д.
Этот подход также выполняется за линейное время, но не создает полную копию дерева. Следовательно, использование памяти составляет только O (d), где d - глубина дерева. В худшем случае это O (n), но, по всей вероятности, намного лучше.