Bird
Raised Fist0
DSA Typescriptprogramming~15 mins

Mirror a Binary Tree in DSA Typescript - Deep Dive

Choose your learning style10 modes available
Overview - Mirror a Binary Tree
What is it?
Mirroring a binary tree means creating a new tree where the left and right children of all nodes are swapped. Imagine flipping the tree around its center so that the left side becomes the right side and vice versa. This operation changes the structure but keeps the values intact. It helps us understand tree transformations and symmetry.
Why it matters
Mirroring a binary tree helps in problems where we want to check if two trees are mirror images or to transform data structures for easier processing. Without this concept, we would struggle to handle symmetrical data or perform certain tree-based algorithms efficiently. It also deepens understanding of tree traversal and manipulation, which are fundamental in many applications like graphics, databases, and AI.
Where it fits
Before learning to mirror a binary tree, you should understand what a binary tree is and how to traverse it (preorder, inorder, postorder). After mastering mirroring, you can explore tree symmetry checks, tree rotations, and advanced tree algorithms like AVL or Red-Black trees.
Mental Model
Core Idea
Mirroring a binary tree means swapping every node's left and right children recursively to create a flipped version of the original tree.
Think of it like...
It's like looking at yourself in a mirror: your left hand appears as the right hand in the reflection, and everything is reversed left-to-right.
Original Tree:           Mirrored Tree:
    1                         1
   / \                       / \
  2   3                     3   2
 / \   \                   /   / \
4   5   6                 6   5   4
Build-Up - 6 Steps
1
FoundationUnderstanding Binary Tree Structure
šŸ¤”
Concept: Learn what a binary tree is and how nodes connect with left and right children.
A binary tree is a structure where each node has up to two children: left and right. Each node holds a value and pointers to its children or null if none. For example, a node with value 1 might have left child 2 and right child 3.
Result
You can visualize and represent trees with nodes and links to left and right children.
Understanding the basic structure of binary trees is essential before manipulating or transforming them.
2
FoundationTraversing Binary Trees Recursively
šŸ¤”
Concept: Learn how to visit each node in a tree using recursion.
Recursion means a function calls itself to process smaller parts. For trees, you visit a node, then recursively visit its left child, then right child. This helps process or modify every node systematically.
Result
You can write functions that reach every node in the tree without missing any.
Mastering recursion on trees is key to applying transformations like mirroring.
3
IntermediateSwapping Left and Right Children
šŸ¤”Before reading on: do you think swapping children at just the root node is enough to mirror the whole tree? Commit to yes or no.
Concept: Mirroring requires swapping left and right children at every node, not just the root.
At each node, swap its left and right children pointers. Then repeat this process recursively for each child node. This ensures the entire tree is flipped, not just the top level.
Result
The tree's structure is reversed at every level, producing a mirror image.
Knowing that mirroring is a recursive process prevents incomplete or incorrect transformations.
4
IntermediateImplementing Mirror Function in TypeScript
šŸ¤”Before reading on: do you think the mirror function should return a new tree or modify the original tree? Commit to your answer.
Concept: You can write a function that modifies the original tree in place by swapping children recursively.
function mirrorTree(node: TreeNode | null): TreeNode | null { if (node === null) return null; const left = mirrorTree(node.left); const right = mirrorTree(node.right); node.left = right; node.right = left; return node; } This function visits each node, swaps its children, and returns the modified node.
Result
The original tree is transformed into its mirror image after calling mirrorTree(root).
Understanding in-place modification saves memory and is efficient for large trees.
5
AdvancedHandling Edge Cases and Empty Trees
šŸ¤”Before reading on: do you think an empty tree or a single-node tree changes after mirroring? Commit to yes or no.
Concept: Mirroring must correctly handle empty trees and trees with one node without errors.
If the node is null, return null immediately. If the node has no children, swapping does nothing but the function still returns the node. This ensures the function is safe for all inputs.
Result
Empty trees remain empty, single-node trees remain unchanged, and larger trees are mirrored correctly.
Handling edge cases prevents runtime errors and ensures robustness.
6
ExpertIterative Mirroring Using a Stack
šŸ¤”Before reading on: do you think mirroring can be done without recursion? Commit to yes or no.
Concept: Mirroring can be done iteratively using a stack to avoid recursion and control memory usage.
function mirrorTreeIterative(root: TreeNode | null): TreeNode | null { if (root === null) return null; const stack: TreeNode[] = [root]; while (stack.length > 0) { const node = stack.pop()!; [node.left, node.right] = [node.right, node.left]; if (node.left) stack.push(node.left); if (node.right) stack.push(node.right); } return root; } This uses a stack to visit nodes and swap children without recursion.
Result
The tree is mirrored correctly without using the call stack.
Knowing iterative methods helps avoid stack overflow in very deep trees and improves control over execution.
Under the Hood
Mirroring works by recursively or iteratively visiting each node and swapping its left and right child pointers. This changes the tree's structure in memory by redirecting links. The process uses depth-first traversal to ensure all nodes are processed. In recursion, the call stack keeps track of nodes; in iteration, an explicit stack does this.
Why designed this way?
Recursion naturally fits tree structures because trees are defined recursively. Swapping children at each node is the simplest way to flip the tree. Alternatives like creating a new tree copy are more memory-intensive. The design balances simplicity, efficiency, and clarity.
Start
  │
  ā–¼
Visit Node
  │
  ā–¼
Swap Left and Right Children
  │
  ā–¼
Recursively Mirror Left Child ←────┐
  │                               │
  ā–¼                               │
Recursively Mirror Right Child ā”€ā”€ā”€ā”˜
  │
  ā–¼
Return Mirrored Node
  │
  ā–¼
End
Myth Busters - 4 Common Misconceptions
Quick: Does mirroring a tree change the values inside the nodes? Commit to yes or no.
Common Belief:Mirroring changes the values of the nodes to their opposites or some transformation.
Tap to reveal reality
Reality:Mirroring only swaps the positions of nodes; the values inside nodes remain exactly the same.
Why it matters:Believing values change can lead to incorrect assumptions about data integrity after mirroring.
Quick: Is swapping children at the root node enough to mirror the entire tree? Commit to yes or no.
Common Belief:Swapping left and right children at the root node alone mirrors the whole tree.
Tap to reveal reality
Reality:You must swap children at every node recursively; otherwise, only the top level is flipped.
Why it matters:Partial swapping leads to incorrect or incomplete mirroring, causing bugs in algorithms relying on full symmetry.
Quick: Can mirroring be done without recursion? Commit to yes or no.
Common Belief:Mirroring must be done recursively because trees are recursive structures.
Tap to reveal reality
Reality:Mirroring can also be done iteratively using a stack or queue to avoid recursion.
Why it matters:Knowing iterative methods helps handle very deep trees without risking stack overflow.
Quick: Does mirroring a tree always produce a balanced tree? Commit to yes or no.
Common Belief:Mirroring a tree balances it or improves its shape.
Tap to reveal reality
Reality:Mirroring only flips the tree; it does not change its balance or height properties.
Why it matters:Assuming mirroring balances trees can mislead optimization and performance expectations.
Expert Zone
1
Mirroring a tree in place modifies the original structure, which may not be desirable if the original tree is needed later; cloning before mirroring is sometimes necessary.
2
Iterative mirroring can be optimized by using a queue for breadth-first traversal, which mirrors the tree level by level.
3
In functional programming, mirroring is often implemented by creating a new mirrored tree rather than modifying the original, preserving immutability.
When NOT to use
Avoid in-place mirroring when the original tree must remain unchanged; instead, create a mirrored copy. Also, do not use mirroring to balance trees; use rotations or balancing algorithms like AVL or Red-Black trees instead.
Production Patterns
Mirroring is used in graphics to flip scene graphs, in testing to verify symmetric tree properties, and in algorithms that require comparing tree structures for mirror equality. It also appears in serialization/deserialization processes where tree orientation matters.
Connections
Tree Traversal Algorithms
Mirroring builds on recursive tree traversal patterns like preorder and postorder.
Understanding traversal helps grasp how mirroring visits and processes every node systematically.
Symmetry in Geometry
Mirroring a binary tree is analogous to geometric reflection symmetry.
Recognizing this connection helps understand the concept of flipping structures around an axis.
Undo/Redo Operations in Software
Mirroring is similar to reversing actions by swapping states, like undoing changes.
Knowing mirroring helps understand how data structures can be transformed and reverted efficiently.
Common Pitfalls
#1Trying to mirror only the root node's children without recursion.
Wrong approach:function mirrorTree(node: TreeNode | null): TreeNode | null { if (node === null) return null; [node.left, node.right] = [node.right, node.left]; return node; }
Correct approach:function mirrorTree(node: TreeNode | null): TreeNode | null { if (node === null) return null; const left = mirrorTree(node.left); const right = mirrorTree(node.right); node.left = right; node.right = left; return node; }
Root cause:Misunderstanding that mirroring requires swapping children at every node, not just the root.
#2Not handling null nodes leading to runtime errors.
Wrong approach:function mirrorTree(node: TreeNode): TreeNode { [node.left, node.right] = [node.right, node.left]; mirrorTree(node.left); mirrorTree(node.right); return node; }
Correct approach:function mirrorTree(node: TreeNode | null): TreeNode | null { if (node === null) return null; const left = mirrorTree(node.left); const right = mirrorTree(node.right); node.left = right; node.right = left; return node; }
Root cause:Failing to check for null before recursive calls causes errors on leaf nodes.
#3Assuming mirroring changes node values.
Wrong approach:function mirrorTree(node: TreeNode | null): TreeNode | null { if (node === null) return null; node.value = -node.value; // Incorrect value change const left = mirrorTree(node.left); const right = mirrorTree(node.right); node.left = right; node.right = left; return node; }
Correct approach:function mirrorTree(node: TreeNode | null): TreeNode | null { if (node === null) return null; const left = mirrorTree(node.left); const right = mirrorTree(node.right); node.left = right; node.right = left; return node; }
Root cause:Confusing structural transformation with data modification.
Key Takeaways
Mirroring a binary tree means swapping the left and right children of every node recursively to create a flipped version.
This operation changes the tree's shape but keeps all node values unchanged.
Recursion naturally fits mirroring because trees are recursive structures, but iterative methods can also be used.
Handling edge cases like empty or single-node trees ensures the mirror function is robust.
Understanding mirroring deepens knowledge of tree traversal and manipulation, which are fundamental in many algorithms.

Practice

(1/5)
1. What does it mean to mirror a binary tree?
easy
A. Swap the left and right children of every node in the tree
B. Remove all leaf nodes from the tree
C. Convert the tree into a linked list
D. Sort the tree nodes in ascending order

Solution

  1. Step 1: Understand the mirror operation

    Mirroring a binary tree means swapping the left and right children of every node.
  2. Step 2: Effect on the tree structure

    This operation flips the tree around its center, creating a mirror image.
  3. Final Answer:

    Swap the left and right children of every node in the tree -> Option A
  4. Quick Check:

    Mirror = Swap children [OK]
Hint: Mirror means swapping left and right children at all nodes [OK]
Common Mistakes:
  • Thinking mirror means sorting nodes
  • Confusing mirror with removing nodes
  • Assuming mirror changes node values
2. Which of the following TypeScript function signatures correctly represents a function to mirror a binary tree node?
easy
A. function mirrorTree(root: string): string
B. function mirrorTree(root: number): number
C. function mirrorTree(root: TreeNode): void
D. function mirrorTree(root: TreeNode | null): TreeNode | null

Solution

  1. Step 1: Identify the input and output types

    The function should accept a TreeNode or null and return a TreeNode or null after mirroring.
  2. Step 2: Check each option's signature

    function mirrorTree(root: TreeNode | null): TreeNode | null matches the expected input and output types for a binary tree mirror function.
  3. Final Answer:

    function mirrorTree(root: TreeNode | null): TreeNode | null -> Option D
  4. Quick Check:

    Correct signature uses TreeNode or null [OK]
Hint: Mirror function inputs and outputs TreeNode or null [OK]
Common Mistakes:
  • Using primitive types like number or string instead of TreeNode
  • Returning void instead of the mirrored tree
  • Not allowing null as input
3. Given the following TypeScript code, what is the output when the tree is mirrored and then printed in preorder?
class TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
  constructor(val: number, left: TreeNode | null = null, right: TreeNode | null = null) {
    this.val = val;
    this.left = left;
    this.right = right;
  }
}

function mirrorTree(root: TreeNode | null): TreeNode | null {
  if (!root) return null;
  const left = mirrorTree(root.left);
  const right = mirrorTree(root.right);
  root.left = right;
  root.right = left;
  return root;
}

function preorder(root: TreeNode | null): number[] {
  if (!root) return [];
  return [root.val, ...preorder(root.left), ...preorder(root.right)];
}

const tree = new TreeNode(1, new TreeNode(2, new TreeNode(4), new TreeNode(5)), new TreeNode(3));
const mirrored = mirrorTree(tree);
console.log(preorder(mirrored));
medium
A. [1, 2, 4, 5, 3]
B. [1, 3, 2, 5, 4]
C. [1, 3, 5, 4, 2]
D. [1, 2, 5, 4, 3]

Solution

  1. Step 1: Understand the original tree structure

    The tree is:
    1
    ā”œā”€ 2
    │ ā”œā”€ 4
    │ └─ 5
    └─ 3
  2. Step 2: Mirror the tree by swapping left and right children

    After mirroring:
    1
    ā”œā”€ 3
    └─ 2
    ā”œā”€ 5
    └─ 4
  3. Step 3: Preorder traversal of mirrored tree

    Preorder visits root, left, right:
    1, 3, 2, 5, 4
  4. Final Answer:

    [1, 3, 2, 5, 4] -> Option B
  5. Quick Check:

    Mirror preorder = [1, 3, 2, 5, 4] [OK]
Hint: Mirror swaps children; preorder visits root-left-right [OK]
Common Mistakes:
  • Not swapping children correctly
  • Confusing preorder with inorder or postorder
  • Forgetting to mirror recursively
4. The following TypeScript function is intended to mirror a binary tree but contains a bug. What is the bug?
function mirrorTree(root: TreeNode | null): TreeNode | null {
  if (!root) return null;
  mirrorTree(root.left);
  mirrorTree(root.right);
  const temp = root.left;
  root.left = root.right;
  root.right = temp;
  return root;
}
medium
A. The base case should return root instead of null
B. The swapping of left and right children is done before recursion
C. The recursive calls do not assign the mirrored subtrees back to root.left and root.right
D. The function does not handle empty trees

Solution

  1. Step 1: Analyze the recursive calls

    The function calls mirrorTree on root.left and root.right but does not assign the results back to root.left and root.right.
  2. Step 2: Understand the effect of missing assignments

    Without assigning, the subtrees are not updated with their mirrored versions, so the mirror is incomplete.
  3. Final Answer:

    The recursive calls do not assign the mirrored subtrees back to root.left and root.right -> Option C
  4. Quick Check:

    Assign recursive results to children [OK]
Hint: Always assign recursive mirror results back to children [OK]
Common Mistakes:
  • Ignoring return values of recursive calls
  • Swapping children before recursion
  • Incorrect base case handling
5. You have a binary tree where some nodes have only one child (either left or right). After mirroring the tree using the standard mirror function, which of the following statements is true about the structure of the mirrored tree?
hard
A. Nodes with only left child will have only right child after mirroring
B. Nodes with only left child will have no children after mirroring
C. Nodes with only right child will have both children after mirroring
D. The tree structure remains unchanged after mirroring

Solution

  1. Step 1: Understand mirroring effect on single-child nodes

    Mirroring swaps left and right children of every node.
  2. Step 2: Effect on nodes with only one child

    If a node has only a left child, after mirroring, that child becomes the right child, and left becomes null.
  3. Final Answer:

    Nodes with only left child will have only right child after mirroring -> Option A
  4. Quick Check:

    Mirror swaps children, single left child becomes right [OK]
Hint: Mirror swaps children, single left child moves to right [OK]
Common Mistakes:
  • Assuming children disappear after mirroring
  • Thinking mirroring adds children
  • Believing tree structure stays same
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard