39

I was looking at interview questions and I recently came upon one that asked you how to reverse a general binary tree, like flip it from right to left.

So for example if we had the binary tree

     6
   /   \
  3     4
 / \   / \
7   3 8   1

Reversing it would create

     6
   /   \
  4     3
 / \   / \
1   8 3   7

You can see that the new tree is the mirror image of the original tree.

I haven't been able to think of a good implementation on how to solve this problem. Can anyone offer any good ideas?

tgdavies
  • 10,307
  • 4
  • 35
  • 40
user1234831
  • 409
  • 1
  • 4
  • 5

6 Answers6

103

You can use recursion. We swap the left and right child of a node, in-place, and then do the same for its children:

static void reverseTree(final TreeNode root) {
    final TreeNode temp = root.right;
    root.right = root.left;
    root.left = temp;
    
    if (root.left != null) {
        reverseTree(root.left);
    }
    
    if (root.right != null) {
        reverseTree(root.right);
    }
}

To handle the case where the parameter root may be null:

static void reverseTree(final TreeNode root) {
    if (root == null) {
        return;
    }
    
    final TreeNode temp = root.right;
    root.right = root.left;
    root.left = temp;
    
    reverseTree(root.left);
    
    reverseTree(root.right);
}
mic
  • 1,190
  • 1
  • 17
  • 29
Petar Ivanov
  • 91,536
  • 11
  • 82
  • 95
27

Reverse a binary tree in O(1) in C/C++.

struct NormalNode {
  int value;
  struct NormalNode *left;
  struct NormalNode *right;
};

struct ReversedNode {
  int value;
  struct ReversedNode *right;
  struct ReversedNode *left;
};

struct ReversedNode *reverseTree(struct NormalNode *root) {
  return (struct ReversedNode *)root;
}
mic
  • 1,190
  • 1
  • 17
  • 29
Zhipeng YANG
  • 797
  • 9
  • 18
5

There are a couple interesting parts to this question. First, since your language is Java, you're most likely to have a generic Node class, something like this:

class Node<T> {
    private final T data;
    private final Node left;
    private final Node right;
    public Node<T>(final T data, final Node left, final Node right) {
        this.data  = data;
        this.left  = left;
        this.right = right;
    }
    ....
}

Secondly, reversing, sometimes called inverting, can be done either by mutating the left and right fields of the node, or by creating a new node just like the original but with its left and right children "reversed." The former approach is shown in another answer, while the second approach is shown here:

class Node<T> {
    // See fields and constructor above...

    public Node<T> reverse() {
        Node<T> newLeftSubtree = right == null ? null : right.reverse();
        Node<T> newRightSubtree = left == null ? null : left.reverse();
        return Node<T>(data, newLeftSubtree, newRightSubtree); 
    }
}

The idea of not mutating a data structure is one of the ideas behind persistent data structures, which are pretty interesting.

Community
  • 1
  • 1
Ray Toal
  • 86,166
  • 18
  • 182
  • 232
  • shouldn't the right be the left reverse and the left the the right reverse? – kapad Jun 11 '15 at 19:55
  • The swapping is done when constructing a new Node: i.e. that's why the right comes before the left. It is not clear because the constructor has not been given. – amnn Jun 12 '15 at 06:58
  • Good call, @amnn and thanks for the initial edit. Java's lack of named arguments is a bit of a bummer, being able to say `new Node(data=data, left=right?.reverse(), right=left?.reverse())` would be awesome but Java is not there yet. We could also do `new Node().withData(data).withLeft(right.reverse.......).withRight(left.reverse......)` etc. I ended up just making the `reverse` method a little more readable by using named local variables. – Ray Toal Jun 13 '15 at 03:45
0

You can recursively swap the left and right nodes as below;

// helper method
private static void reverseTree(TreeNode<Integer> root) {
    reverseTreeNode(root);
}

private static void reverseTreeNode(TreeNode<Integer> node) {
    TreeNode<Integer> temp = node.left;
    node.left   = node.right;
    node.right  = temp;

    if(node.left != null)
        reverseTreeNode(node.left);

    if(node.right != null)
        reverseTreeNode(node.right);
}

Demonstration Code for Java

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

public class InvertBinaryTreeDemo {

    public static void main(String[] args) {

        // root node
        TreeNode<Integer> root  = new TreeNode<>(6);

        // children of root
        root.left               = new TreeNode<Integer>(3);
        root.right              = new TreeNode<Integer>(4);

        // grand left children of root
        root.left.left          = new TreeNode<Integer>(7);
        root.left.right         = new TreeNode<Integer>(3);

        // grand right childrend of root
        root.right.left         = new TreeNode<Integer>(8);
        root.right.right        = new TreeNode<Integer>(1);

        System.out.println("Before invert");
        traverseTree(root);

        reverseTree(root);

        System.out.println("\nAfter invert");
        traverseTree(root);
    }

    // helper method
    private static void reverseTree(TreeNode<Integer> root) {
        reverseTreeNode(root);
    }

    private static void reverseTreeNode(TreeNode<Integer> node) {
        TreeNode<Integer> temp = node.left;
        node.left   = node.right;
        node.right  = temp;

        if(node.left != null)
            reverseTreeNode(node.left);

        if(node.right != null)
            reverseTreeNode(node.right);
    }

    // helper method for traverse
    private static void traverseTree(TreeNode<Integer> root) {
        Queue<Integer> leftChildren     = new LinkedList<>();
        Queue<Integer> rightChildren    = new LinkedList<>();

        traverseTreeNode(root, leftChildren, rightChildren);

        System.out.println("Tree;\n*****");

        System.out.printf("%3d\n", root.value);

        int count = 0;
        int div = 0;
        while(!(leftChildren.isEmpty() && rightChildren.isEmpty())) {
            System.out.printf("%3d\t%3d\t", leftChildren.poll(), rightChildren.poll());
            count += 2;
            div++;
            if( (double)count == (Math.pow(2, div))) {
                System.out.println();
                count = 0;
            }
        }

        System.out.println();
    }

    private static void traverseTreeNode(TreeNode<Integer> node, Queue<Integer> leftChildren, Queue<Integer> rightChildren) {
        if(node.left != null)
            leftChildren.offer(node.left.value);

        if(node.right != null)
            rightChildren.offer(node.right.value);

        if(node.left != null) {
            traverseTreeNode(node.left, leftChildren, rightChildren);
        }

        if(node.right != null) {
            traverseTreeNode(node.right, leftChildren, rightChildren);
        }
    }

    private static class TreeNode<E extends Comparable<E>> {

        protected E value;
        protected TreeNode<E> left;
        protected TreeNode<E> right;

        public TreeNode(E value) {
            this.value = value;
            this.left = null;
            this.right = null;
        }

    }

}

Output

Before invert
Tree;
*****
  6
  3   4 
  7   3   8   1 

After invert
Tree;
*****
  6
  4   3 
  1   8   3   7 
Levent Divilioglu
  • 11,198
  • 5
  • 59
  • 106
0

The recursion function can be very simple as shown below:

public Node flipTree(Node node) {
    if(node == null) return null;

    Node left = flipTree(node.left);
    Node right = flipTree(node.right);

    node.left = right;
    node.right = left;

    return node;
}
Ajay Singh
  • 95
  • 2
  • 10
  • 2
    Please refrain from answering code-only. At least demonstrate why it solves the problem, and explain the code, either in text or comments, so that future readers will be able to understand it. – Adriaan Oct 16 '18 at 15:41
  • 1
    To be fair the top voted answer also is code-only. That being said, it's worth looking at existing answers before adding your own. Your answer is exactly the same as the top voted answer so in general it's better to just upvote that answer rather than add your own duplicate answer. – aug Dec 11 '18 at 19:01
-1

I've seen most of the answers aren't focussing on null pointer issues.

public static Node invertBinaryTree(Node node) {

    if(node != null) {
        Node temp = node.getLeftChild();

        node.setLeftChild(node.getRightChild());
        node.setRigthChild(temp);

        if(node.left!=null) { 
            invertBinaryTree(node.getLeftChild());
        }
        if(node.right !=null) {
            invertBinaryTree(node.getRightChild());
        }
    }

    return node;
}

In the code above we are making recursive calls only if the left/right child of the root node isn't null. Its one of the fastest approach!

Sidd Thota
  • 2,040
  • 1
  • 20
  • 24