5 Best Ways to Create a Mirror Copy of a Binary Tree and Display Using BFS Traversal in Python

Rate this post

πŸ’‘ Problem Formulation: Creating a mirror copy of a binary tree involves flipping the tree horizontally so that each left child becomes a right child and vice versa, effectively creating a mirrored version. Additionally, displaying the mirrored tree with a Breadth-First Search (BFS) traversal provides a level-wise output. This article tackles the input of a binary tree and demonstrates various Pythonic methods to output its mirrored counterpart using BFS.

Method 1: Recursive mirroring with BFS display

This method uses a recursive function to create a mirror copy of a binary tree by swapping the left and right child nodes at each step. Once mirrored, it uses a BFS traversal to display the levels of the tree. It’s a straightforward approach that utilizes the call stack for mirroring the tree structure.

Here’s an example:

class TreeNode:
    def __init__(self, value):
        self.val = value
        self.left = None
        self.right = None

def mirror_tree(root):
    if root is None:
        return None
    root.left, root.right = mirror_tree(root.right), mirror_tree(root.left)
    return root

def bfs_display(root):
    if not root:
        return []
    queue, result = [root], []
    while queue:
        level = []
        for _ in range(len(queue)):
            node = queue.pop(0)
            level.append(node.val)
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)
        result.append(level)
    return result

# Setup a sample tree
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)

mirrored_root = mirror_tree(root)
print(bfs_display(mirrored_root))

Output:

[[1], [3, 2], [5, 4]]

This code creates a binary tree and then calls mirror_tree() to get the mirrored tree. Finally, it uses bfs_display() to display the mirrored tree level by level. It uses queues to keep track of nodes to visit in BFS manner and a nested loop to move through each level.

Method 2: Iterative mirroring with BFS display

The iterative method for creating a mirror copy of a binary tree relies on a queue to traverse the tree while swapping left and right children at each node. By avoiding recursion, this approach circumvents possible stack overflow issues with large trees. Display is again achieved via BFS.

Here’s an example:

from collections import deque

def mirror_tree_iterative(root):
    if not root:
        return None
    queue = deque([root])
    while queue:
        node = queue.popleft()
        if node:
            node.left, node.right = node.right, node.left
            queue.append(node.left)
            queue.append(node.right)
    return root

# The bfs_display function remains the same as above

mirrored_root = mirror_tree_iterative(root)
print(bfs_display(mirrored_root))

Output:

[[1], [3, 2], [5, 4]]

This snippet defines mirror_tree_iterative() which iteratively creates a mirror of the existing binary tree. By using a deque for more efficient pops from the left, it processes nodes level by level, swapping left and right children, again followed by a BFS display.

Method 3: Stack-based mirroring with BFS display

This method utilizes a stack for mirroring a tree iteratively. The LIFO nature of stacks helps mimic the recursive approach to a certain extent, making it a good alternative for large trees where recursion depth could be an issue.

Here’s an example:

def mirror_tree_stack(root):
    if not root:
        return None
    stack = [root]
    while stack:
        node = stack.pop()
        node.left, node.right = node.right, node.left
        if node.left:
            stack.append(node.left)
        if node.right:
            stack.append(node.right)
    return root

# The bfs_display function remains the same as Method 1

mirrored_root = mirror_tree_stack(root)
print(bfs_display(mirrored_root))

Output:

[[1], [3, 2], [5, 4]]

In the provided code, mirror_tree_stack() is used to mirror the binary tree using a stack. Similar to the iterative queue method, the stack is used to process each node and swap children, followed by a BFS to display the mirrored tree.

Method 4: In-place mirroring with BFS display

In-place mirroring is done by directly altering the original tree without the use of additional data structures for node storage. This method is space-efficient and maintains the tree structure succinctly.

Here’s an example:

# The mirror_tree() function from Method 1 can perform in-place mirroring.
# The bfs_display function remains the same as Method 1

mirrored_root = mirror_tree(root)
print(bfs_display(mirrored_root))

Output:

[[1], [3, 2], [5, 4]]

In this code snippet, the mirror_tree() function from Method 1 is reused as it already performs in-place mirroring. The same BFS display function is used to showcase the mirrored tree structure.

Bonus One-Liner Method 5: Functional mirroring with BFS display

A one-liner for tree mirroring can be achieved by using Python’s lambda functions. This method is compact and pythonic. Note, however, that readability might suffer for those not familiar with Python’s functional programming features.

Here’s an example:

mirror_tree_one_liner = lambda root: (mirror_tree_one_liner(root.right), mirror_tree_one_liner(root.left)) if root else None

# The bfs_display function remains the same as Method 1

mirrored_root = mirror_tree_one_liner(root)
print(bfs_display(mirrored_root))

Output:

[[1], [3, 2], [5, 4]]

This clever one-liner uses a lambda function to perform the mirror operation in a single expression. It shows the power and conciseness of Python’s lambda functions, but should be used with caution for the sake of code clarity.

Summary/Discussion

  • Method 1: Recursive Mirroring with BFS. Strengths: Simple and intuitive. Weaknesses: Recursive method may lead to stack overflow for very deep trees.
  • Method 2: Iterative Mirroring with BFS. Strengths: Avoids recursion issues and is efficient. Weaknesses: Slightly more complex than the recursive method.
  • Method 3: Stack-based Mirroring with BFS. Strengths: Good alternative to recursion, preserving the order of processing. Weaknesses: Not as intuitive as recursion.
  • Method 4: In-place Mirroring with BFS. Strengths: Space-efficient as it alters the original tree. Weaknesses: Can be destructive to the original tree structure.
  • Bonus Method 5: Functional One-Liner with BFS. Strengths: Very compact and elegant. Weaknesses: Reduced readability for unfamiliar programmers.