Algorithm for finding symmetries of a tree
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Finding symmetries of a tree means finding automorphisms: ways to map the tree onto itself while preserving adjacency. For trees, this is much easier than for general graphs because trees have no cycles and admit clean canonical representations. The practical algorithm is to root the tree at its center, compute canonical signatures for subtrees, and then use repeated identical signatures to detect where symmetric swaps are possible.
Step 1: Find the Tree Center
For an unrooted tree, symmetry should be analyzed from the center, not from an arbitrary node. A tree has either:
- one center node
- two adjacent center nodes
You can find the center by repeatedly peeling leaves until one or two nodes remain.
Why this matters: if you root the tree at a random leaf, the encoding of the tree depends on that arbitrary choice and hides global symmetry.
Step 2: Build a Canonical Form Bottom-Up
Once the tree is rooted at its center, compute a canonical signature for every subtree. A standard idea is:
- compute the signatures of all children
- sort the child signatures
- wrap the sorted list in parentheses
A leaf gets the signature ().
Example Python code for a rooted tree signature:
If two rooted subtrees have the same signature, they are isomorphic.
Step 3: Use Repeated Child Signatures to Detect Symmetry
The signature itself tells you where symmetry exists. If a node has several children with identical subtree signatures, those children can be permuted without changing the tree.
For example, if a node has child signatures:
Then:
- the two leaf children are interchangeable
- the two
(()())subtrees are interchangeable
Those repeated groups are the source of automorphisms.
This is why canonical labeling is powerful: it converts the structural question into grouping equal subtree encodings.
Mirror Symmetry as a Simpler Case
Sometimes the real question is only whether the tree is symmetric with respect to a reflection, not the full automorphism group. In that simpler case, the test is:
- root at the center
- at each node, child subtrees must be pairable by identical signatures
- if there is one unpaired child, that child must itself be symmetric around its own root
A recursive check can express this idea.
This checks a reflection-style symmetry, not every automorphism.
Counting Symmetries
If you want the number of automorphisms rather than just detecting symmetry, identical child groups matter again. If a node has k children with the same subtree signature, those subtrees can be permuted in k! ways, multiplied by the automorphism counts inside each child subtree.
That leads to a dynamic-programming style count on the rooted tree.
The full counting logic is more involved, but the main insight is simple: equal canonical subtree types are what create permutations.
Complexity
With a reasonable implementation, canonical labeling on a tree is efficient. The expensive-looking part is sorting child signatures, but the total work is still manageable because each edge participates only once in the rooted traversal.
For ordinary tree sizes, this is dramatically better than trying all node permutations, which becomes infeasible almost immediately.
Common Pitfalls
The most common mistake is rooting the tree arbitrarily. For unrooted symmetry, you need to start at the tree center or the result can be misleading.
Another mistake is brute-forcing permutations of vertices. Trees allow much better structure-aware algorithms based on canonical forms.
Developers also often mix up two questions: whether the tree has any nontrivial symmetry versus how many automorphisms it has. The second problem is richer and needs counting logic.
Finally, be careful about rooted versus unrooted trees. A symmetry that preserves an unrooted tree may disappear once you force a specific root.
Summary
- Find the tree center first for unrooted symmetry analysis.
- Compute canonical subtree signatures bottom-up.
- Identical child signatures reveal interchangeable subtrees and therefore symmetries.
- Reflection-style symmetry can be checked recursively from grouped child signatures.
- Full automorphism counting builds on the same canonical-form idea without brute-forcing permutations.

