Skip to main content
2 of 3
edited tags
Rohit Jain
  • 690
  • 3
  • 6
  • 16

Printing a Binary Tree top-down (column wise)

We have a binary tree, suppose like this:

       8
     /   \
    6     10
   / \   /  \
  4   7 9    12
 / \
3   5

We have to print this binary tree in top-down manner - column wise. Note that, 8, 7 & 9 would be considered in same column. So the required output should be:

3
4
6 5
8 7 9
10
12

Currently I've implemented this problem using two maps, and one queue. Here's the method traversal(Node<T> node), which is invoked first time, passing the root node:

public void traverse(Node<T> node) {
    
    Queue<Node<T>> queue = new LinkedList<>();
    
    Map<Integer, List<Node<T>>> columnMap = new TreeMap<>();
    Map<Node<T>, Integer> map = new HashMap<>();
    
    queue.add(node);
    
    while (!queue.isEmpty()) {
        
        Node<T> temp = queue.poll();
        
        if (map.isEmpty()) {
            map.put(temp, 0);
            columnMap.put(0, new ArrayList<Node<T>>(Arrays.asList(temp)));
        }
        
        int column = map.get(temp);
        
        if (temp.left() != null) {
            queue.add(temp.left());
            
            if (columnMap.containsKey(column - 1)) {
                columnMap.get(column - 1).add(temp.left());
            } else {
                columnMap.put(column - 1, new ArrayList<Node<T>>(Arrays.asList(temp.left())));
            }
            
            map.put(temp.left(), column - 1);
        }
        
        if (temp.right() != null) {
            queue.add(temp.right());
            
            if (columnMap.containsKey(column + 1)) {
                columnMap.get(column + 1).add(temp.right());
            } else {
                columnMap.put(column + 1, new ArrayList<Node<T>>(Arrays.asList(temp.right())));
            }
            
            map.put(temp.right(), column + 1);
        }
    }
    
    for (Entry<Integer, List<Node<T>>> entry: columnMap.entrySet()) {
        System.out.println("Column - " + entry.getKey() + " : " + entry.getValue());
    }
}

The idea is, starting from root node as column number 0, the left node will have column number -1, and the right node will have column number 1. Then the right node of the left node will again have column number 0. And similarly I proceed till I've exhausted all the nodes. I've used level order traversal for traversing.

The first map - Map<Node<T>, Integer> is used to get the column number for a particular node. And the second map - Map<Integer, List<Node<T>>> is used to map each column number with a list of node on that column. I thought of getting it done with just a single map, but I found it more clear.

Is there some better option? Currently, the code looks a bit complex to me. May be it can be improvised? I'm open to a completely different implementation too, provided it is more clear, and space and time efficient.

Rohit Jain
  • 690
  • 3
  • 6
  • 16