Given a Binary Tree, the task is to find its vertical traversal starting from the leftmost level to the rightmost level. Note that if multiple nodes at same level pass through a vertical line, they should be printed as they appear in the level order traversal of the tree.
Examples:
Input:
Output: [[4], [2], [1, 5, 6], [3, 8], [7], [9]] Explanation: The below image shows the horizontal distances used to print vertical traversal starting from the leftmost level to the rightmost level.
Approach:
The idea is to traverse the tree once and get the minimum and maximum horizontal distance with respect to root. For the tree shown above, minimum distance is -2 (for node with value 4) and maximum distance is 3 (For node with value 9). Once we have maximum and minimum distances from root, we iterate for each vertical line at distance minimum to maximum from root, and for each vertical line traverse the tree and print the nodes which lie on that vertical line.
C++
//Driver Code Starts// C++ code of Vertical Traversal using Brute Force#include<iostream>#include<vector>usingnamespacestd;classNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=nullptr;right=nullptr;}};//Driver Code Ends// A utility function to find min and max // distances with respect to root.voidfindMinMax(Node*node,int&min,int&max,inthd){// Base caseif(node==nullptr)return;// Update min and maxif(hd<min)min=hd;elseif(hd>max)max=hd;// Recur for left and right subtreesfindMinMax(node->left,min,max,hd-1);findMinMax(node->right,min,max,hd+1);}// A utility function to collect all // nodes on a given vertical line_no.// hd is horizontal distance of current node with respect to root.voidcollectVerticalLine(Node*node,intline,inthd,vector<int>&res){// Base caseif(node==nullptr)return;// If this node is on the given vertical lineif(hd==line)res.push_back(node->data);// Recur for left and right subtreescollectVerticalLine(node->left,line,hd-1,res);collectVerticalLine(node->right,line,hd+1,res);}// The main function that returns a // vector of nodes in vertical ordervector<vector<int>>verticalOrder(Node*root){vector<vector<int>>res;// Find min and max distances with // respect to rootintmin=0,max=0;findMinMax(root,min,max,0);// Iterate through all possible vertical// lines from leftmost to rightmostfor(intline=min;line<=max;line++){vector<int>verticalNodes;collectVerticalLine(root,line,0,verticalNodes);res.push_back(verticalNodes);}returnres;}//Driver Code Startsintmain(){// Create binary tree// 1// / \ // 2 3// / \ / \ // 4 5 6 7// \ \ // 8 9Node*root=newNode(1);root->left=newNode(2);root->right=newNode(3);root->left->left=newNode(4);root->left->right=newNode(5);root->right->left=newNode(6);root->right->right=newNode(7);root->right->left->right=newNode(8);root->right->right->right=newNode(9);vector<vector<int>>res=verticalOrder(root);// Print grouped vertical nodesfor(vector<int>group:res){cout<<"[ ";for(intval:group)cout<<val<<" ";cout<<"] ";}cout<<endl;return0;}//Driver Code Ends
Java
//Driver Code Starts// Java code of Vertical Traversal using Brute Forceimportjava.util.ArrayList;classNode{intdata;Nodeleft,right;Node(intx){data=x;left=null;right=null;}}classGfG{//Driver Code Ends// A utility function to find min and max // distances with respect to root.staticvoidfindMinMax(Nodenode,int[]minMax,inthd){// Base caseif(node==null)return;// Update min and maxif(hd<minMax[0])minMax[0]=hd;elseif(hd>minMax[1])minMax[1]=hd;// Recur for left and right subtreesfindMinMax(node.left,minMax,hd-1);findMinMax(node.right,minMax,hd+1);}// A utility function to collect all // nodes on a given vertical line_no.staticvoidcollectVerticalLine(Nodenode,intlineNo,inthd,ArrayList<Integer>res){// Base caseif(node==null)return;// If this node is on the given vertical lineif(hd==lineNo)res.add(node.data);// Recur for left and right subtreescollectVerticalLine(node.left,lineNo,hd-1,res);collectVerticalLine(node.right,lineNo,hd+1,res);}// The main function that returns an ArrayList of ArrayLists// representing vertical order traversalstaticArrayList<ArrayList<Integer>>verticalOrder(Noderoot){ArrayList<ArrayList<Integer>>res=newArrayList<>();// Find min and max distances with respect to rootint[]minMax=newint[]{0,0};findMinMax(root,minMax,0);// Iterate through all possible vertical // lines from leftmost to rightmostfor(intlineNo=minMax[0];lineNo<=minMax[1];lineNo++){ArrayList<Integer>verticalNodes=newArrayList<>();collectVerticalLine(root,lineNo,0,verticalNodes);res.add(verticalNodes);}returnres;}//Driver Code Startspublicstaticvoidmain(String[]args){// Create binary tree// 1// / \// 2 3// / \ / \// 4 5 6 7// \ \// 8 9Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);root.right.left.right=newNode(8);root.right.right.right=newNode(9);ArrayList<ArrayList<Integer>>res=verticalOrder(root);// Print grouped vertical nodesfor(ArrayList<Integer>group:res){System.out.print("[ ");for(intval:group){System.out.print(val+" ");}System.out.print("] ");}System.out.println();}}//Driver Code Ends
Python
#Driver Code Starts# Python code of Vertical Traversal # using Brute ForceclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=None#Driver Code Ends# A utility function to find min and max# distances with respect to root.deffindMinMax(node,minMax,hd):ifnodeisNone:return# Update min and maxifhd<minMax[0]:minMax[0]=hdelifhd>minMax[1]:minMax[1]=hd# Recur for left and right subtreesfindMinMax(node.left,minMax,hd-1)findMinMax(node.right,minMax,hd+1)# A utility function to collect all # nodes on a given vertical line_no.defcollectVerticalLine(node,lineNo,hd,res):ifnodeisNone:return# If this node is on the given vertical lineifhd==lineNo:res.append(node.data)# Recur for left and right subtreescollectVerticalLine(node.left,lineNo,hd-1,res)collectVerticalLine(node.right,lineNo,hd+1,res)# The main function that returns a list of lists# of nodes in vertical orderdefverticalOrder(root):res=[]# Find min and max distances with respect to rootminMax=[0,0]findMinMax(root,minMax,0)# Iterate through all possible vertical linesforlineNoinrange(minMax[0],minMax[1]+1):verticalNodes=[]collectVerticalLine(root,lineNo,0,verticalNodes)res.append(verticalNodes)returnres#Driver Code Startsif__name__=="__main__":# Create binary tree# 1# / \# 2 3# / \ / \# 4 5 6 7# \ \# 8 9root=Node(1)root.left=Node(2)root.right=Node(3)root.left.left=Node(4)root.left.right=Node(5)root.right.left=Node(6)root.right.right=Node(7)root.right.left.right=Node(8)root.right.right.right=Node(9)res=verticalOrder(root)# Print grouped vertical nodesfortempinres:print("["," ".join(map(str,temp)),"]",end=" ")print()#Driver Code Ends
C#
//Driver Code Starts// C# code of Vertical Traversal using Brute ForceusingSystem;usingSystem.Collections.Generic;classNode{publicintdata;publicNodeleft,right;publicNode(intx){data=x;left=null;right=null;}}classGfG{//Driver Code Ends// A utility function to find min and// max distances with respect to root.staticvoidfindMinMax(Nodenode,int[]minMax,inthd){// Base caseif(node==null)return;// Update min and maxif(hd<minMax[0])minMax[0]=hd;elseif(hd>minMax[1])minMax[1]=hd;// Recur for left and right subtreesfindMinMax(node.left,minMax,hd-1);findMinMax(node.right,minMax,hd+1);}// A utility function to collect all// nodes on a given vertical lineNo.staticvoidcollectVerticalLine(Nodenode,intlineNo,inthd,List<int>res){// Base caseif(node==null)return;// If this node is on the // given vertical lineif(hd==lineNo)res.Add(node.data);// Recur for left and right subtreescollectVerticalLine(node.left,lineNo,hd-1,res);collectVerticalLine(node.right,lineNo,hd+1,res);}// The main function that returns a list// of lists of nodes in vertical orderstaticList<List<int>>verticalOrder(Noderoot){List<List<int>>res=newList<List<int>>();// Find min and max distances with respect to rootint[]minMax=newint[]{0,0};findMinMax(root,minMax,0);// Iterate through all possible vertical linesfor(intlineNo=minMax[0];lineNo<=minMax[1];lineNo++){List<int>verticalNodes=newList<int>();collectVerticalLine(root,lineNo,0,verticalNodes);res.Add(verticalNodes);}returnres;}//Driver Code StartspublicstaticvoidMain(){// Create binary tree// 1// / \// 2 3// / \ / \// 4 5 6 7// \ \// 8 9Noderoot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);root.right.left.right=newNode(8);root.right.right.right=newNode(9);List<List<int>>res=verticalOrder(root);// Print grouped vertical nodesforeach(vartempinres){Console.Write("[ ");foreach(intvalintemp){Console.Write(val+" ");}Console.Write("] ");}Console.WriteLine();}}//Driver Code Ends
JavaScript
//Driver Code Starts// JavaScript code of Vertical Traversal using Brute ForceclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}//Driver Code Ends// A utility function to find min// and max distances with respect to root.functionfindMinMax(node,minMax,hd){// Base caseif(node===null)return;// Update min and maxif(hd<minMax[0])minMax[0]=hd;elseif(hd>minMax[1])minMax[1]=hd;// Recur for left and right subtreesfindMinMax(node.left,minMax,hd-1);findMinMax(node.right,minMax,hd+1);}// A utility function to collect all// nodes on a given vertical lineNo.functioncollectVerticalLine(node,lineNo,hd,res){// Base caseif(node===null)return;// If this node is on the given vertical lineif(hd===lineNo)res.push(node.data);// Recur for left and right subtreescollectVerticalLine(node.left,lineNo,hd-1,res);collectVerticalLine(node.right,lineNo,hd+1,res);}// The main function that returns an // array of arrays of nodes in vertical orderfunctionverticalOrder(root){letres=[];// Find min and max distances with respect to rootletminMax=[0,0];findMinMax(root,minMax,0);// Iterate through all possible vertical linesfor(letlineNo=minMax[0];lineNo<=minMax[1];lineNo++){letverticalNodes=[];collectVerticalLine(root,lineNo,0,verticalNodes);res.push(verticalNodes);}returnres;}//Driver Code Starts// Driver codeif(require.main===module){// Create binary tree// 1// / \// 2 3// / \ / \// 4 5 6 7// \ \// 8 9letroot=newNode(1);root.left=newNode(2);root.right=newNode(3);root.left.left=newNode(4);root.left.right=newNode(5);root.right.left=newNode(6);root.right.right=newNode(7);root.right.left.right=newNode(8);root.right.right.right=newNode(9);letres=verticalOrder(root);console.log(res.map(arr=>`[ ${arr.join(" ")} ]`).join(" "));}//Driver Code Ends
Output
[ 4 ] [ 2 ] [ 1 5 6 ] [ 3 8 ] [ 7 ] [ 9 ]
Time Complexity: O(n2), Time complexity of above algorithm is O(w*n) where w is width of Binary Tree and n is number of nodes in Binary Tree. In worst case, the value of w can be O(n). Auxiliary Space: O(h), space use by memory stack, where h is height of the tree. Please refer the below posts for optimised solutions.