Print root to leaf paths without using recursion
Given a binary tree, print all its root-to-leaf paths without using recursion. For example, consider the following Binary Tree.
6
/ \
3 5
/ \ \
2 5 4
/ \
7 4
There are 4 leaves, hence 4 root to leaf paths -
6->3->2
6->3->5->7
6->3->5->4
6->5>4
We strongly recommend you to minimize your browser and try this yourself first.
We can traverse tree iteratively (we have used iterative preorder). The question is, how to extend the traversal to print root-to-leaf paths? The idea is to maintain a map to store parent pointers of binary tree nodes. Now whenever we encounter a leaf node while doing iterative preorder traversal, we can easily print root to leaf path using parent pointer.
Below is the implementation of this idea.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node
{
int data;
struct Node *left, *right;
};
Node* newNode( int data)
{
Node* node = new Node;
node->data = data;
node->left = node->right = NULL;
return node;
}
void printTopToBottomPath(Node* curr,
map<Node*, Node*> parent)
{
stack<Node*> stk;
while (curr)
{
stk.push(curr);
curr = parent[curr];
}
while (!stk.empty())
{
curr = stk.top();
stk.pop();
cout << curr->data << " " ;
}
cout << endl;
}
void printRootToLeaf(Node* root)
{
if (root == NULL)
return ;
stack<Node*> nodeStack;
nodeStack.push(root);
map<Node*, Node*> parent;
parent[root] = NULL;
while (!nodeStack.empty())
{
Node* current = nodeStack.top();
nodeStack.pop();
if (!(current->left) && !(current->right))
printTopToBottomPath(current, parent);
if (current->right)
{
parent[current->right] = current;
nodeStack.push(current->right);
}
if (current->left)
{
parent[current->left] = current;
nodeStack.push(current->left);
}
}
}
int main()
{
Node* root = newNode(10);
root->left = newNode(8);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(5);
root->right->left = newNode(2);
printRootToLeaf(root);
return 0;
}
|
Java
import java.util.Stack;
import java.util.HashMap;
public class PrintPath {
public static void printTopToBottomPath(Node curr, HashMap<Node,Node> parent)
{
Stack<Node> stk= new Stack<>() ;
while (curr!= null )
{
stk.push(curr);
curr = parent.get(curr);
}
while (!stk.isEmpty())
{
curr = stk.pop();
System.out.print(curr.data+ " " );
}
System.out.println();
}
public static void printRootToLeaf(Node root)
{
if (root == null )
return ;
Stack<Node> nodeStack= new Stack<>();
nodeStack.push(root);
HashMap<Node,Node> parent= new HashMap<>();
parent.put(root, null );
while (!nodeStack.isEmpty())
{
Node current = nodeStack.pop();
if (current.left== null && current.right== null )
printTopToBottomPath(current, parent);
if (current.right!= null )
{
parent.put(current.right,current);
nodeStack.push(current.right);
}
if (current.left!= null )
{
parent.put(current.left,current);
nodeStack.push(current.left);
}
}
}
public static void main(String args[]) {
Node root= new Node( 10 );
root.left = new Node( 8 );
root.right = new Node( 2 );
root.left.left = new Node( 3 );
root.left.right = new Node( 5 );
root.right.left = new Node( 2 );
printRootToLeaf(root);
}
}
class Node
{
int data;
Node left, right;
Node( int data)
{
left=right= null ;
this .data=data;
}
};
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = self .right = None
def printTopToBottomPath(curr, parent):
stk = []
while (curr):
stk.append(curr)
curr = parent[curr]
while len (stk) ! = 0 :
curr = stk[ - 1 ]
stk.pop( - 1 )
print (curr.data, end = " " )
print ()
def printRootToLeaf(root):
if (root = = None ):
return
nodeStack = []
nodeStack.append(root)
parent = {}
parent[root] = None
while len (nodeStack) ! = 0 :
current = nodeStack[ - 1 ]
nodeStack.pop( - 1 )
if ( not (current.left) and
not (current.right)):
printTopToBottomPath(current, parent)
if (current.right):
parent[current.right] = current
nodeStack.append(current.right)
if (current.left):
parent[current.left] = current
nodeStack.append(current.left)
if __name__ = = '__main__' :
root = newNode( 10 )
root.left = newNode( 8 )
root.right = newNode( 2 )
root.left.left = newNode( 3 )
root.left.right = newNode( 5 )
root.right.left = newNode( 2 )
printRootToLeaf(root)
|
C#
using System;
using System.Collections.Generic;
public class PrintPath
{
public static void printTopToBottomPath(Node curr,
Dictionary<Node,Node> parent)
{
Stack<Node> stk = new Stack<Node>() ;
while (curr != null )
{
stk.Push(curr);
curr = parent[curr];
}
while (stk.Count != 0)
{
curr = stk.Pop();
Console.Write(curr.data + " " );
}
Console.WriteLine();
}
public static void printRootToLeaf(Node root)
{
if (root == null )
return ;
Stack<Node> nodeStack = new Stack<Node>();
nodeStack.Push(root);
Dictionary<Node,Node> parent = new Dictionary<Node,Node>();
parent.Add(root, null );
while (nodeStack.Count != 0)
{
Node current = nodeStack.Pop();
if (current.left == null && current.right == null )
printTopToBottomPath(current, parent);
if (current.right != null )
{
parent.Add(current.right,current);
nodeStack.Push(current.right);
}
if (current.left != null )
{
parent.Add(current.left,current);
nodeStack.Push(current.left);
}
}
}
public static void Main(String []args)
{
Node root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(2);
printRootToLeaf(root);
}
}
public class Node
{
public int data;
public Node left, right;
public Node( int data)
{
left = right = null ;
this .data = data;
}
};
|
Javascript
<script>
function printTopToBottomPath(curr, parent)
{
var stk = [];
while (curr != null )
{
stk.push(curr);
curr = parent.get(curr);
}
while (stk.length != 0)
{
curr = stk[stk.length-1];
stk.pop();
document.write(curr.data + " " );
}
document.write( "<br>" );
}
function printRootToLeaf(root)
{
if (root == null )
return ;
var nodeStack = [];
nodeStack.push(root);
var parent = new Map();
parent.set(root, null );
while (nodeStack.length != 0)
{
var current = nodeStack[nodeStack.length-1];
nodeStack.pop();
if (current.left == null && current.right == null )
printTopToBottomPath(current, parent);
if (current.right != null )
{
parent.set(current.right,current);
nodeStack.push(current.right);
}
if (current.left != null )
{
parent.set(current.left,current);
nodeStack.push(current.left);
}
}
}
class Node
{
constructor(data)
{
this .left = null ;
this .data = data;
this .right = null ;
}
}
var root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(2);
printRootToLeaf(root);
</script>
|
Output
10 8 3
10 8 5
10 2 2
Time Complexity: O(n log(n)), where n is the total nodes in binary tree.
Auxiliary Space: O(n).
Another Approach:
This method is an optimization of the previous one. The problem can be solved without maintaining a parent pointer or the use of any additional extra space other than stack. We can store the path from root to leaf in a string as we traverse iteratively and print the path as soon as we encounter any leaf node.
Below is the implementation of above idea.
C++
#include <bits/stdc++.h>
using namespace std;
struct Node {
int data;
Node *left, *right;
};
Node* newNode( int data)
{
Node* temp = new Node();
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
bool isleafnode(Node* root)
{
return !root->left && !root->right;
}
void printRootToLeaf(Node* root)
{
if (!root)
return ;
string path = "" ;
stack<pair<Node*, string> > s;
s.push({ root, path });
while (!s.empty()) {
auto it = s.top();
s.pop();
root = it.first;
path = it.second;
string curr = to_string(root->data) + " " ;
path += curr;
if (isleafnode(root))
cout << path << endl;
if (root->right)
s.push({ root->right, path });
if (root->left)
s.push({ root->left, path });
}
}
int main()
{
Node* root = newNode(10);
root->left = newNode(8);
root->right = newNode(2);
root->left->left = newNode(3);
root->left->right = newNode(5);
root->right->left = newNode(2);
printRootToLeaf(root);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static class Node {
int data;
Node left, right;
Node( int data)
{
this .data = data;
this .left = this .right = null ;
}
};
static boolean isleafnode(Node root)
{
return root.left == null && root.right == null ;
}
static class pair {
Node first;
String second;
pair(Node f, String s)
{
first = f;
second = new String(s);
}
}
static void printRootToLeaf(Node root)
{
if (root == null )
return ;
String path = "" ;
Stack<pair> s = new Stack<>();
s.push( new pair(root, path));
while (!s.isEmpty()) {
pair it = s.peek();
s.pop();
root = it.first;
path = it.second;
String curr = (root.data) + " " ;
path += curr;
if (isleafnode(root))
System.out.println(path);
if (root.right != null )
s.push( new pair(root.right, path));
if (root.left != null )
s.push( new pair(root.left, path));
}
}
public static void main(String[] args)
{
Node root = new Node( 10 );
root.left = new Node( 8 );
root.right = new Node( 2 );
root.left.left = new Node( 3 );
root.left.right = new Node( 5 );
root.right.left = new Node( 2 );
printRootToLeaf(root);
}
}
|
Python3
class Node:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def newNode(data):
temp = Node(data)
return temp
def isleafnode(root):
return not root.left and not root.right
def printRootToLeaf(root):
if not root:
return
path = ""
s = []
s.append((root, path))
while len (s) > 0 :
it = s.pop()
root = it[ 0 ]
path = it[ 1 ]
curr = str (root.data) + " "
path + = curr
if isleafnode(root):
print (path)
if root.right:
s.append((root.right, path))
if root.left:
s.append((root.left, path))
root = newNode( 10 )
root.left = newNode( 8 )
root.right = newNode( 2 )
root.left.left = newNode( 3 )
root.left.right = newNode( 5 )
root.right.left = newNode( 2 )
printRootToLeaf(root)
|
C#
using System;
using System.Linq;
using System.Collections.Generic;
class GFG {
class Node {
public int data;
public Node left, right;
public Node( int data)
{
left = right = null ;
this .data = data;
}
}
static bool isleafnode(Node root)
{
return root.left== null && root.right== null ;
}
static void printRootToLeaf(Node root)
{
if (root== null )
return ;
string path = "" ;
Stack<Tuple<Node, string > > s= new Stack<Tuple<Node, string >>();
s.Push(Tuple.Create(root, path));
while (s.Count>0) {
Tuple<Node, string > it = s.Peek();
s.Pop();
root = it.Item1;
path = it.Item2;
string curr = root.data.ToString() + " " ;
path += curr;
if (isleafnode(root))
Console.WriteLine(path);
if (root.right!= null )
s.Push(Tuple.Create(root.right, path));
if (root.left!= null )
s.Push(Tuple.Create(root.left, path));
}
}
public static void Main ( string [] args)
{
Node root = new Node(10);
root.left = new Node(8);
root.right = new Node(2);
root.left.left = new Node(3);
root.left.right = new Node(5);
root.right.left = new Node(2);
printRootToLeaf(root);
}
}
|
Javascript
class Node{
constructor(data){
this .data = data;
this .left = null ;
this .right = null ;
}
}
class pair{
constructor(val1, val2){
this .first = val1;
this .second = val2;
}
}
function newNode(data){
let temp = new Node(data);
return temp;
}
function isleafnode(root){
if (root.left == null && root.right == null ) return true ;
return false ;
}
function printRootToLeaf(root){
if (root == null ) return ;
let path = "" ;
let s = [];
s.push( new pair(root, path));
while (s.length > 0){
let it = s.pop();
root = it.first;
path = it.second;
let curr = (root.data).toString() + " " ;
path = path + curr;
if (isleafnode(root))
console.log(path);
if (root.right != null )
s.push( new pair(root.right, path));
if (root.left != null )
s.push( new pair(root.left, path));
}
}
let root = newNode(10);
root.left = newNode(8);
root.right = newNode(2);
root.left.left = newNode(3);
root.left.right = newNode(5);
root.right.left = newNode(2);
printRootToLeaf(root);
|
Output
10 8 3
10 8 5
10 2 2
Time Complexity: O(n), where n refers to total nodes in a binary tree.
Auxiliary Space: O(n).
Last Updated :
24 Jan, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...