Merging Two Binary Trees in Java: DFS and BFS Implementations

The problem of merging two binary trees involves overlaying one tree onto another. When nodes from both trees overlap, their values are summed to create the value of the new node. If a node exists in only one of the trees, it is directly transferred to the resulting structure. This operation can be efficiently performed using either Depth-First Search (DFS) or Breadth-First Search (BFS).

Depth-First Search Strategy

Recursive traversal is generally preferred for this task due to its conciseness. The algorithm visits nodes starting from the root and proceeds down to the leaves. The merging logic is applied at each step of the recursion.

The core logic hendles three scenarios:

  • If both nodes at the current position are null, return null.
  • If one node is null, return the non-null node to attach it to the result.
  • If both nodes exist, sum their values and recursively process their left and right children.

The following implementation modifies the first tree in place to save space, though creating a new tree is also valid.

/**
 * Definition for a binary tree node.
 */
class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode() {}
    TreeNode(int val) { this.val = val; }
    TreeNode(int val, TreeNode left, TreeNode right) {
        this.val = val;
        this.left = left;
        this.right = right;
    }
}

class Solution {
    public TreeNode mergeTrees(TreeNode treeA, TreeNode treeB) {
        // If the first node is missing, use the second node
        if (treeA == null) {
            return treeB;
        }
        // If the second node is missing, keep the first node
        if (treeB == null) {
            return treeA;
        }
        
        // Both nodes exist: sum the values
        treeA.val += treeB.val;
        
        // Recursively merge the left and right subtrees
        treeA.left = mergeTrees(treeA.left, treeB.left);
        treeA.right = mergeTrees(treeA.right, treeB.right);
        
        return treeA;
    }
}

Breadth-First Search Strategy

An iterative approach using queues is suitable if avoiding recursion depth limits is a priority. This method processes the trees level by level. It typically involves maintaining separate queues for the result tree and the two input trees to synchronize traversal.

Unlike the recursive solution above, this implementation constructs a complete new tree structure rather than modifying an eixsting one.

import java.util.LinkedList;
import java.util.Queue;

class Solution {
    public TreeNode mergeTreesIterative(TreeNode rootA, TreeNode rootB) {
        if (rootA == null) return rootB;
        if (rootB == null) return rootA;
        
        // Initialize the root of the merged tree
        TreeNode mergedRoot = new TreeNode(rootA.val + rootB.val);
        
        // Queues to manage traversal for result, tree A, and tree B
        Queue<TreeNode> resultQueue = new LinkedList<>();
        Queue<TreeNode> queueA = new LinkedList<>();
        Queue<TreeNode> queueB = new LinkedList<>();
        
        resultQueue.offer(mergedRoot);
        queueA.offer(rootA);
        queueB.offer(rootB);
        
        while (!queueA.isEmpty() && !queueB.isEmpty()) {
            TreeNode current = resultQueue.poll();
            TreeNode nodeA = queueA.poll();
            TreeNode nodeB = queueB.poll();
            
            // Handle left children
            TreeNode leftChildA = nodeA.left;
            TreeNode leftChildB = nodeB.left;
            
            if (leftChildA != null || leftChildB != null) {
                if (leftChildA != null && leftChildB != null) {
                    TreeNode newLeft = new TreeNode(leftChildA.val + leftChildB.val);
                    current.left = newLeft;
                    resultQueue.offer(newLeft);
                    queueA.offer(leftChildA);
                    queueB.offer(leftChildB);
                } else if (leftChildA != null) {
                    current.left = leftChildA;
                } else {
                    current.left = leftChildB;
                }
            }
            
            // Handle right children
            TreeNode rightChildA = nodeA.right;
            TreeNode rightChildB = nodeB.right;
            
            if (rightChildA != null || rightChildB != null) {
                if (rightChildA != null && rightChildB != null) {
                    TreeNode newRight = new TreeNode(rightChildA.val + rightChildB.val);
                    current.right = newRight;
                    resultQueue.offer(newRight);
                    queueA.offer(rightChildA);
                    queueB.offer(rightChildB);
                } else if (rightChildA != null) {
                    current.right = rightChildA;
                } else {
                    current.right = rightChildB;
                }
            }
        }
        
        return mergedRoot;
    }
}

Tags: java LeetCode binary-tree depth-first-search breadth-first-search

Posted on Thu, 15 Oct 2026 16:34:27 +0000 by TenFold