[Approach - 1] Using Recursion - O(n) Time and O(h) Space
The boundary traversal of a binary tree is done in three steps. First, we traverse the left boundary, starting from the rootâs left child and moving downward, excluding any leaf nodes. Next, we collect all the leaf nodes of the tree from left to right using recursion. Finally, we traverse the right boundary, starting from the rootâs right child and moving downward, again excluding leaf nodes, but the collected nodes are added in reverse order. By combining the left boundary, leaf nodes, and right boundary, we obtain the complete anti-clockwise boundary traversal of the tree.
C++
#include<iostream>#include<vector>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};boolisLeaf(Node*node){returnnode->left==nullptr&&node->right==nullptr;}// Function to collect left boundary nodes// (top-down order)voidcollectLeft(Node*root,vector<int>&res){// exclude leaf nodeif(root==nullptr||isLeaf(root))return;res.push_back(root->data);if(root->left)collectLeft(root->left,res);elseif(root->right)collectLeft(root->right,res);}// Function to collect all leaf nodes voidcollectLeaves(Node*root,vector<int>&res){if(root==nullptr)return;// Add leaf nodesif(isLeaf(root)){res.push_back(root->data);return;}collectLeaves(root->left,res);collectLeaves(root->right,res);}// Function to collect right boundary nodes// (bottom-up order)voidcollectRight(Node*root,vector<int>&res){// exclude leaf nodesif(root==nullptr||isLeaf(root))return;if(root->right)collectRight(root->right,res);elseif(root->left)collectRight(root->left,res);res.push_back(root->data);}// Function to find Boundary Traversal of Binary Treevector<int>boundaryTraversal(Node*root){vector<int>res;if(!root)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.push_back(root->data);// Collect left boundarycollectLeft(root->left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root->right,res);returnres;}intmain(){// Input 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->left->right->left=newNode(8);root->left->right->right=newNode(9);vector<int>boundary=boundaryTraversal(root);for(intx:boundary)cout<<x<<" ";return0;}
Java
importjava.util.ArrayList;importjava.util.List;// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGFG{staticbooleanisLeaf(Nodenode){returnnode.left==null&&node.right==null;}// Function to collect left boundary nodes// (top-down order)staticvoidcollectLeft(Noderoot,ArrayList<Integer>res){// exclude leaf nodeif(root==null||isLeaf(root))return;res.add(root.data);if(root.left!=null)collectLeft(root.left,res);elseif(root.right!=null)collectLeft(root.right,res);}// Function to collect all leaf nodes staticvoidcollectLeaves(Noderoot,ArrayList<Integer>res){if(root==null)return;// Add leaf nodesif(isLeaf(root)){res.add(root.data);return;}collectLeaves(root.left,res);collectLeaves(root.right,res);}// Function to collect right boundary nodes// (bottom-up order)staticvoidcollectRight(Noderoot,ArrayList<Integer>res){// exclude leaf nodesif(root==null||isLeaf(root))return;if(root.right!=null)collectRight(root.right,res);elseif(root.left!=null)collectRight(root.left,res);res.add(root.data);}// Function to find Boundary Traversal of Binary TreestaticArrayList<Integer>boundaryTraversal(Noderoot){ArrayList<Integer>res=newArrayList<>();if(root==null)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.add(root.data);// Collect left boundarycollectLeft(root.left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root.right,res);returnres;}publicstaticvoidmain(String[]args){// Input 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.left.right.left=newNode(8);root.left.right.right=newNode(9);List<Integer>boundary=boundaryTraversal(root);for(intx:boundary)System.out.print(x+" ");}}
Python
# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefisLeaf(node):returnnode.leftisNoneandnode.rightisNone# Function to collect left boundary nodes# (top-down order)defcollectLeft(root,res):# exclude leaf nodeifrootisNoneorisLeaf(root):returnres.append(root.data)ifroot.left:collectLeft(root.left,res)elifroot.right:collectLeft(root.right,res)# Function to collect all leaf nodes defcollectLeaves(root,res):ifrootisNone:return# Add leaf nodesifisLeaf(root):res.append(root.data)returncollectLeaves(root.left,res)collectLeaves(root.right,res)# Function to collect right boundary nodes# (bottom-up order)defcollectRight(root,res):# exclude leaf nodesifrootisNoneorisLeaf(root):returnifroot.right:collectRight(root.right,res)elifroot.left:collectRight(root.left,res)res.append(root.data)# Function to find Boundary Traversal of Binary TreedefboundaryTraversal(root):res=[]ifnotroot:returnres# Add root data if it's not a leafifnotisLeaf(root):res.append(root.data)# Collect left boundarycollectLeft(root.left,res)# Collect leaf nodescollectLeaves(root,res)# Collect right boundarycollectRight(root.right,res)returnresif__name__=="__main__":# Input 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.left.right.left=Node(8)root.left.right.right=Node(9)boundary=boundaryTraversal(root)forxinboundary:print(x,end=" ")
C#
usingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{staticboolisLeaf(Nodenode){returnnode.left==null&&node.right==null;}// Function to collect left boundary nodes// (top-down order)staticvoidcollectLeft(Noderoot,List<int>res){// exclude leaf nodeif(root==null||isLeaf(root))return;res.Add(root.data);if(root.left!=null)collectLeft(root.left,res);elseif(root.right!=null)collectLeft(root.right,res);}// Function to collect all leaf nodes staticvoidcollectLeaves(Noderoot,List<int>res){if(root==null)return;// Add leaf nodesif(isLeaf(root)){res.Add(root.data);return;}collectLeaves(root.left,res);collectLeaves(root.right,res);}// Function to collect right boundary nodes// (bottom-up order)staticvoidcollectRight(Noderoot,List<int>res){// exclude leaf nodesif(root==null||isLeaf(root))return;if(root.right!=null)collectRight(root.right,res);elseif(root.left!=null)collectRight(root.left,res);res.Add(root.data);}// Function to find Boundary Traversal of Binary TreestaticList<int>boundaryTraversal(Noderoot){List<int>res=newList<int>();if(root==null)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.Add(root.data);// Collect left boundarycollectLeft(root.left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root.right,res);returnres;}staticvoidMain(string[]args){// Input 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.left.right.left=newNode(8);root.left.right.right=newNode(9);List<int>boundary=boundaryTraversal(root);foreach(intxinboundary)Console.Write(x+" ");}}
JavaScript
// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionisLeaf(node){returnnode.left===null&&node.right===null;}// Function to collect left boundary nodes// (top-down order)functioncollectLeft(root,res){// exclude leaf nodeif(root===null||isLeaf(root))return;res.push(root.data);if(root.left!==null)collectLeft(root.left,res);elseif(root.right!==null)collectLeft(root.right,res);}// Function to collect all leaf nodesfunctioncollectLeaves(root,res){if(root===null)return;// Add leaf nodesif(isLeaf(root)){res.push(root.data);return;}collectLeaves(root.left,res);collectLeaves(root.right,res);}// Function to collect right boundary nodes// (bottom-up order)functioncollectRight(root,res){// exclude leaf nodesif(root===null||isLeaf(root))return;if(root.right!==null)collectRight(root.right,res);elseif(root.left!==null)collectRight(root.left,res);res.push(root.data);}// Function to find Boundary Traversal of Binary TreefunctionboundaryTraversal(root){letres=[];if(root===null)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.push(root.data);// Collect left boundarycollectLeft(root.left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root.right,res);returnres;}// Driver Code// Input 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.left.right.left=newNode(8);root.left.right.right=newNode(9);letboundary=boundaryTraversal(root);console.log(boundary.join(" "));
Output
1 2 4 8 9 6 7 3
[Approach - 2] Using Iteration and Morris Traversal - O(n) Time and O(h) Space
The idea is to reduce the auxiliary space used by the memory stack in the above approach. This approach is similar to the previous one, but instead of recursion, we use iteration to find the left and right boundaries, and use Morris Traversal to find the leaf nodes.
C++
#include<iostream>#include<vector>usingnamespacestd;// Node StructureclassNode{public:intdata;Node*left;Node*right;Node(intx){data=x;left=right=nullptr;}};boolisLeaf(Node*node){returnnode->left==nullptr&&node->right==nullptr;}// Function to collect the left boundary nodesvoidcollectLeft(Node*root,vector<int>&res){if(root==nullptr)return;Node*curr=root;while(!isLeaf(curr)){res.push_back(curr->data);if(curr->left)curr=curr->left;elsecurr=curr->right;}}// Function to collect the leaf nodes using Morris TraversalvoidcollectLeaves(Node*root,vector<int>&res){Node*current=root;while(current){if(current->left==nullptr){// If it's a leaf nodeif(current->right==nullptr)res.push_back(current->data);current=current->right;}else{// Find the inorder predecessorNode*predecessor=current->left;while(predecessor->right&&predecessor->right!=current){predecessor=predecessor->right;}if(predecessor->right==nullptr){predecessor->right=current;current=current->left;}else{// If it's predecessor is a leaf nodeif(predecessor->left==nullptr)res.push_back(predecessor->data);predecessor->right=nullptr;current=current->right;}}}}// Function to collect the right boundary nodesvoidcollectRight(Node*root,vector<int>&res){if(root==nullptr)return;Node*curr=root;vector<int>temp;while(!isLeaf(curr)){temp.push_back(curr->data);if(curr->right)curr=curr->right;elsecurr=curr->left;}for(inti=temp.size()-1;i>=0;--i)res.push_back(temp[i]);}// Function to perform boundary traversalvector<int>boundaryTraversal(Node*root){vector<int>res;if(!root)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.push_back(root->data);// Collect left boundarycollectLeft(root->left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root->right,res);returnres;}intmain(){// Hardcoded 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->left->right->left=newNode(8);root->left->right->right=newNode(9);vector<int>boundary=boundaryTraversal(root);for(intx:boundary)cout<<x<<" ";return0;}
Java
importjava.util.ArrayList;importjava.util.List;// Node StructureclassNode{intdata;Nodeleft,right;Node(intx){data=x;left=right=null;}}classGFG{staticbooleanisLeaf(Nodenode){returnnode.left==null&&node.right==null;}// Function to collect the left boundary nodesstaticvoidcollectLeft(Noderoot,ArrayList<Integer>res){if(root==null)return;Nodecurr=root;while(!isLeaf(curr)){res.add(curr.data);if(curr.left!=null)curr=curr.left;elsecurr=curr.right;}}// Function to collect the leaf nodes using Morris TraversalstaticvoidcollectLeaves(Noderoot,ArrayList<Integer>res){Nodecurrent=root;while(current!=null){if(current.left==null){// If it's a leaf nodeif(current.right==null)res.add(current.data);current=current.right;}else{// Find the inorder predecessorNodepredecessor=current.left;while(predecessor.right!=null&&predecessor.right!=current){predecessor=predecessor.right;}if(predecessor.right==null){predecessor.right=current;current=current.left;}else{// If its predecessor is a leaf nodeif(predecessor.left==null)res.add(predecessor.data);predecessor.right=null;current=current.right;}}}}// Function to collect the right boundary nodesstaticvoidcollectRight(Noderoot,ArrayList<Integer>res){if(root==null)return;Nodecurr=root;ArrayList<Integer>temp=newArrayList<>();while(!isLeaf(curr)){temp.add(curr.data);if(curr.right!=null)curr=curr.right;elsecurr=curr.left;}for(inti=temp.size()-1;i>=0;--i)res.add(temp.get(i));}// Function to perform boundary traversalstaticArrayList<Integer>boundaryTraversal(Noderoot){ArrayList<Integer>res=newArrayList<>();if(root==null)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.add(root.data);// Collect left boundarycollectLeft(root.left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root.right,res);returnres;}publicstaticvoidmain(String[]args){// Hardcoded 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.left.right.left=newNode(8);root.left.right.right=newNode(9);ArrayList<Integer>boundary=boundaryTraversal(root);for(intx:boundary)System.out.print(x+" ");}}
Python
# Node StructureclassNode:def__init__(self,x):self.data=xself.left=Noneself.right=NonedefisLeaf(node):returnnode.leftisNoneandnode.rightisNone# Function to collect the left boundary nodesdefcollectLeft(root,res):ifrootisNone:returncurr=rootwhilenotisLeaf(curr):res.append(curr.data)ifcurr.leftisnotNone:curr=curr.leftelse:curr=curr.right# Function to collect the leaf nodes using Morris TraversaldefcollectLeaves(root,res):current=rootwhilecurrent:ifcurrent.leftisNone:# If it's a leaf nodeifcurrent.rightisNone:res.append(current.data)current=current.rightelse:# Find the inorder predecessorpredecessor=current.leftwhilepredecessor.rightandpredecessor.right!=current:predecessor=predecessor.rightifpredecessor.rightisNone:predecessor.right=currentcurrent=current.leftelse:# If its predecessor is a leaf nodeifpredecessor.leftisNone:res.append(predecessor.data)predecessor.right=Nonecurrent=current.right# Function to collect the right boundary nodesdefcollectRight(root,res):ifrootisNone:returncurr=roottemp=[]whilenotisLeaf(curr):temp.append(curr.data)ifcurr.rightisnotNone:curr=curr.rightelse:curr=curr.leftforiinreversed(temp):res.append(i)# Function to perform boundary traversaldefboundaryTraversal(root):res=[]ifrootisNone:returnres# Add root data if it's not a leafifnotisLeaf(root):res.append(root.data)# Collect left boundarycollectLeft(root.left,res)# Collect leaf nodescollectLeaves(root,res)# Collect right boundarycollectRight(root.right,res)returnresif__name__=="__main__":# Hardcoded 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.left.right.left=Node(8)root.left.right.right=Node(9)boundary=boundaryTraversal(root)print(" ".join(map(str,boundary)))
C#
usingSystem;usingSystem.Collections.Generic;// Node StructureclassNode{publicintdata;publicNodeleft;publicNoderight;publicNode(intx){data=x;left=right=null;}}classGFG{staticboolisLeaf(Nodenode){returnnode.left==null&&node.right==null;}// Function to collect the left boundary nodesstaticvoidcollectLeft(Noderoot,List<int>res){if(root==null)return;Nodecurr=root;while(!isLeaf(curr)){res.Add(curr.data);if(curr.left!=null)curr=curr.left;elsecurr=curr.right;}}// Function to collect the leaf nodes using Morris TraversalstaticvoidcollectLeaves(Noderoot,List<int>res){Nodecurrent=root;while(current!=null){if(current.left==null){// If it's a leaf nodeif(current.right==null)res.Add(current.data);current=current.right;}else{// Find the inorder predecessorNodepredecessor=current.left;while(predecessor.right!=null&&predecessor.right!=current){predecessor=predecessor.right;}if(predecessor.right==null){predecessor.right=current;current=current.left;}else{// If its predecessor is a leaf nodeif(predecessor.left==null)res.Add(predecessor.data);predecessor.right=null;current=current.right;}}}}// Function to collect the right boundary nodesstaticvoidcollectRight(Noderoot,List<int>res){if(root==null)return;Nodecurr=root;List<int>temp=newList<int>();while(!isLeaf(curr)){temp.Add(curr.data);if(curr.right!=null)curr=curr.right;elsecurr=curr.left;}for(inti=temp.Count-1;i>=0;--i)res.Add(temp[i]);}// Function to perform boundary traversalstaticList<int>boundaryTraversal(Noderoot){List<int>res=newList<int>();if(root==null)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.Add(root.data);// Collect left boundarycollectLeft(root.left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root.right,res);returnres;}staticvoidMain(string[]args){// Hardcoded 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.left.right.left=newNode(8);root.left.right.right=newNode(9);List<int>boundary=boundaryTraversal(root);foreach(intxinboundary)Console.Write(x+" ");}}
JavaScript
// Node StructureclassNode{constructor(x){this.data=x;this.left=null;this.right=null;}}functionisLeaf(node){returnnode.left===null&&node.right===null;}// Function to collect the left boundary nodesfunctioncollectLeft(root,res){if(root===null)return;letcurr=root;while(!isLeaf(curr)){res.push(curr.data);if(curr.left!==null)curr=curr.left;elsecurr=curr.right;}}// Function to collect the leaf nodes using Morris TraversalfunctioncollectLeaves(root,res){letcurrent=root;while(current){if(current.left===null){// If it's a leaf nodeif(current.right===null)res.push(current.data);current=current.right;}else{// Find the inorder predecessorletpredecessor=current.left;while(predecessor.right&&predecessor.right!==current){predecessor=predecessor.right;}if(predecessor.right===null){predecessor.right=current;current=current.left;}else{// If its predecessor is a leaf nodeif(predecessor.left===null)res.push(predecessor.data);predecessor.right=null;current=current.right;}}}}// Function to collect the right boundary nodesfunctioncollectRight(root,res){if(root===null)return;letcurr=root;lettemp=[];while(!isLeaf(curr)){temp.push(curr.data);if(curr.right!==null)curr=curr.right;elsecurr=curr.left;}for(leti=temp.length-1;i>=0;i--)res.push(temp[i]);}// Function to perform boundary traversalfunctionboundaryTraversal(root){letres=[];if(root===null)returnres;// Add root data if it's not a leafif(!isLeaf(root))res.push(root.data);// Collect left boundarycollectLeft(root.left,res);// Collect leaf nodescollectLeaves(root,res);// Collect right boundarycollectRight(root.right,res);returnres;}// Driver Code// Hardcoded 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.left.right.left=newNode(8);root.left.right.right=newNode(9);letboundary=boundaryTraversal(root);console.log(boundary.join(" "));