How do you invert a binary tree, and what does the result look like?
Swap the left and right children of every node. The recursive version returns the inverted subtree so that you can assign both children in one statement, which keeps the swap and the recursion together.
class TreeNode:
def __init__(self, value, left=None, right=None):
self.value = value
self.left = left
self.right = right
def invert(root):
if root is None:
return None
root.left, root.right = invert(root.right), invert(root.left)
return root
def to_list(node, out=None):
if out is None:
out = []
if node:
out.append(node.value)
to_list(node.left, out)
to_list(node.right, out)
return out
tree = TreeNode(4, TreeNode(2, TreeNode(1), TreeNode(3)), TreeNode(7, TreeNode(6), TreeNode(9)))
print(to_list(tree))
print(to_list(invert(tree)))The outputs are 4, 2, 1, 3, 7, 6, 9 and 4, 7, 9, 2, 6, 3, 1. The second list is the first one reflected left to right, with the whole tree mirrored.
The mechanism is that the mirror of a mirror is the original, so you have to invert the children before you swap them. Inverting the right subtree and the left subtree first and then swapping them produces the mirror of the whole subtree, which is exactly what the parent needs. Doing the swap before the recursion would give the wrong answer, because the children would be swapped back by the recursive calls.
The trade-off to name is that the recursion mutates the tree in place, so any other reference to the same nodes sees the inverted structure. If the original tree is needed, you have to copy it first. The cost is linear time with stack space proportional to the height, and for a very deep tree the iterative version in the next answer avoids the stack entirely while doing exactly the same swap on every node.