Print Root-to-Leaf Paths in a Binary Tree
Last Updated :
05 May, 2025
Given a Binary Tree of nodes, the task is to find all the possible paths from the root node to all the leaf nodes of the binary tree.
Note: The paths should be returned such that paths from the left subtree of any node are listed first, followed by paths from the right subtree.
Example:
Input: root[] = [1, 2, 3, 4, 5, N, N]
Output: [[1, 2, 4], [1, 2, 5], [1, 3]]
Explanation: All the possible paths from root node to leaf nodes are: 1 -> 2 -> 4, 1 -> 2 -> 5 and 1 -> 3
Approach: Recursion with Backtracking
The approach involves the use recursion to traverse the given Binary tree. The recursive function will append node values to a path as it navigates down the tree. After reaching a leaf node, the path is stored in the final result. After exploring both left and right subtrees, the function backtracks to explore alternate paths.
C++
// C++ code of print all paths from root node
// to leaf node using recursion.
#include <iostream>
#include <vector>
using namespace std;
class Node{
public:
int data;
Node *left;
Node *right;
Node(int x)
{
data = x;
left = right = nullptr;
}
};
void collectPaths(Node *node, vector<int> &path, vector<vector<int>> &paths)
{
if (node == nullptr)
return;
// Append this node to the path
path.push_back(node->data);
// If it's a leaf node, store the path
if (node->left == nullptr && node->right == nullptr)
{
paths.push_back(path);
}
else
{
// Otherwise, try both subtrees
collectPaths(node->left, path, paths);
collectPaths(node->right, path, paths);
}
// Backtrack: remove the last element
// from the path
path.pop_back();
}
// Function to get all paths from root to leaf
vector<vector<int>> Paths(Node *root)
{
vector<vector<int>> paths;
vector<int> path;
collectPaths(root, path, paths);
return paths;
}
int main(){
Node *root = new Node(1);
root->left = new Node(2);
root->right = new Node(3);
root->left->left = new Node(4);
root->left->right = new Node(5);
vector<vector<int>> res = Paths(root);
for (auto &row : res){
for (int val : row){
cout << val << " ";
}
cout << endl;
}
return 0;
}
Java
// Java code of print all paths from root node
// to leaf node using recursion.
import java.util.ArrayList;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Utility function to collect all root-to-leaf paths
static void collectPaths(Node node, ArrayList<Integer> path,
ArrayList<ArrayList<Integer>> paths) {
if (node == null)
return;
// Append this node to the path
path.add(node.data);
// If it's a leaf node, store the path
if (node.left == null && node.right == null) {
paths.add(new ArrayList<>(path));
}
else {
// Otherwise, try both subtrees
collectPaths(node.left, path, paths);
collectPaths(node.right, path, paths);
}
// Backtrack: remove the last element
// from the path
path.remove(path.size() - 1);
}
// Function to get all paths from root to leaf
static ArrayList<ArrayList<Integer>> Paths(Node root) {
ArrayList<ArrayList<Integer>> paths = new ArrayList<>();
ArrayList<Integer> path = new ArrayList<>();
collectPaths(root, path, paths);
return paths;
}
public static void main(String[] args) {
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
ArrayList<ArrayList<Integer>> res = Paths(root);
for (ArrayList<Integer> row : res) {
for (int val : row) {
System.out.print(val + " ");
}
System.out.println();
}
}
}
Python
# Python code of print all paths from root node
# to leaf node using recursion.
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Utility function to collect all root-to-leaf paths
def collectPaths(node, path, paths):
if node is None:
return
# Append this node to the path
path.append(node.data)
# If it's a leaf node, store the path
if node.left is None and node.right is None:
paths.append(list(path))
else:
# Otherwise, try both subtrees
collectPaths(node.left, path, paths)
collectPaths(node.right, path, paths)
# Backtrack: remove the last element
# from the path
path.pop()
# Function to get all paths from root to leaf
def Paths(root):
paths = []
path = []
collectPaths(root, path, paths)
return paths
if __name__ == "__main__":
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
res = Paths(root)
for row in res:
for val in row:
print(val, end=" ")
print()
C#
// C# code of print all paths from root node
// to leaf node using recursion.
using System;
using System.Collections.Generic;
class Node {
public int data;
public Node left, right;
public Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Utility function to collect all root-to-leaf paths
static void collectPaths(Node node, List<int> path,
List<List<int>> paths) {
if (node == null)
return;
// Append this node to the path
path.Add(node.data);
// If it's a leaf node, store the path
if (node.left == null && node.right == null) {
paths.Add(new List<int>(path));
}
else {
// Otherwise, try both subtrees
collectPaths(node.left, path, paths);
collectPaths(node.right, path, paths);
}
// Backtrack: remove the last element
// from the path
path.RemoveAt(path.Count - 1);
}
// Function to get all paths from root to leaf
static List<List<int>> Paths(Node root) {
List<List<int>> paths = new List<List<int>>();
List<int> path = new List<int>();
collectPaths(root, path, paths);
return paths;
}
static void Main() {
Node root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
List<List<int>> res = Paths(root);
foreach (var row in res) {
foreach (int val in row) {
Console.Write(val + " ");
}
Console.WriteLine();
}
}
}
JavaScript
// JavaScript code of print all paths from root node
// to leaf node using recursion.
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Utility function to collect all root-to-leaf paths
function collectPaths(node, path, paths) {
if (node === null)
return;
// Append this node to the path
path.push(node.data);
// If it's a leaf node, store the path
if (node.left === null && node.right === null) {
paths.push([...path]);
}
else {
// Otherwise, try both subtrees
collectPaths(node.left, path, paths);
collectPaths(node.right, path, paths);
}
// Backtrack: remove the last element
// from the path
path.pop();
}
// Function to get all paths from root to leaf
function Paths(root) {
const paths = [];
const path = [];
collectPaths(root, path, paths);
return paths;
}
const root = new Node(1);
root.left = new Node(2);
root.right = new Node(3);
root.left.left = new Node(4);
root.left.right = new Node(5);
const res = Paths(root);
for (const row of res) {
console.log(row.join(" "));
}
Time Complexity: O(n + L × h),where n
is the number of nodes, L
is the number of leaf nodes, and h
is the height of the tree, since each node is visited once and each root-to-leaf path (up to length h
) is copied at most once.
Auxiliary Space: O(h), where h is the height of tree.
Related articles:
Similar Reads
DSA Tutorial - Learn Data Structures and Algorithms DSA (Data Structures and Algorithms) is the study of organizing data efficiently using data structures like arrays, stacks, and trees, paired with step-by-step procedures (or algorithms) to solve problems effectively. Data structures manage how data is stored and accessed, while algorithms focus on
7 min read
Quick Sort QuickSort is a sorting algorithm based on the Divide and Conquer that picks an element as a pivot and partitions the given array around the picked pivot by placing the pivot in its correct position in the sorted array. It works on the principle of divide and conquer, breaking down the problem into s
12 min read
Merge Sort - Data Structure and Algorithms Tutorials Merge sort is a popular sorting algorithm known for its efficiency and stability. It follows the divide-and-conquer approach. It works by recursively dividing the input array into two halves, recursively sorting the two halves and finally merging them back together to obtain the sorted array. Merge
14 min read
Data Structures Tutorial Data structures are the fundamental building blocks of computer programming. They define how data is organized, stored, and manipulated within a program. Understanding data structures is very important for developing efficient and effective algorithms. What is Data Structure?A data structure is a st
2 min read
Bubble Sort Algorithm Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in the wrong order. This algorithm is not suitable for large data sets as its average and worst-case time complexity are quite high.We sort the array using multiple passes. After the fir
8 min read
Breadth First Search or BFS for a Graph Given a undirected graph represented by an adjacency list adj, where each adj[i] represents the list of vertices connected to vertex i. Perform a Breadth First Search (BFS) traversal starting from vertex 0, visiting vertices from left to right according to the adjacency list, and return a list conta
15+ min read
Binary Search Algorithm - Iterative and Recursive Implementation Binary Search Algorithm is a searching algorithm used in a sorted array by repeatedly dividing the search interval in half. The idea of binary search is to use the information that the array is sorted and reduce the time complexity to O(log N). Binary Search AlgorithmConditions to apply Binary Searc
15 min read
Insertion Sort Algorithm Insertion sort is a simple sorting algorithm that works by iteratively inserting each element of an unsorted list into its correct position in a sorted portion of the list. It is like sorting playing cards in your hands. You split the cards into two groups: the sorted cards and the unsorted cards. T
9 min read
Array Data Structure Guide In this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
4 min read
Sorting Algorithms A Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read