Print ancestors of a given binary tree node without recursion
Given a Binary Tree and a node key. The task is to print all the ancestors of the given key in the tree without using recursion. An ancestor of a node is any node that lies on the path from the root to that node, excluding the node itself.
Note: All node values are unique, and the given key is guaranteed to be present in the tree.
Examples:
Input: key = 7
1
/ \
2 3
/ \
4 5
/ \
7 8
Output: 5 2 1
Explanation: The path from the root (1) to 7 is 1 -> 2 -> 5 -> 7, so its ancestors are 5, 2, and 1.Input: key = 50
10
/ \
20 30
/ \
40 50
Output: 20 10
Explanation: The path from the root (10) to 50 is 10 -> 20 -> 50, so its ancestors are 20 and 10.
A Recursive Solution for this problem is discussed here.
Approach:
The idea is to find the ancestors of a node in a binary tree without using recursion. The approach uses an iterative Depth-First Search (DFS) with a stack to traverse the tree, and a parent mapping to store each node’s parent. Once the node with the key is found, the ancestors are collected by following the parent pointers.
Steps to implement the above idea:
- Create a Node class to represent each tree node with data, left, and right pointers.
- Initialize a stack for DFS traversal and an unordered map called parent to store the parent-child relationships.
- Traverse the tree iteratively using the stack, pushing nodes and their corresponding parent into the map.
- Once the node with the given key is found, start collecting ancestors by tracing the parent pointers.
- Finally, print the collected ancestors after the parent mapping is complete.
// C++ Code to print all ancestors of a given key
// in a Binary Tree without Recursion
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* left;
Node* right;
Node(int x) {
data = x;
left = right = nullptr;
}
};
// Function to find and return ancestors of
// the given key
vector<int> printAncestors(Node* root, int key) {
if (!root) {
return {};
}
unordered_map<Node*, Node*> parent;
stack<Node*> stk;
stk.push(root);
// Build parent mapping using iterative DFS
while (!stk.empty()) {
Node* curr = stk.top();
stk.pop();
if (curr->right) {
parent[curr->right] = curr;
stk.push(curr->right);
}
if (curr->left) {
parent[curr->left] = curr;
stk.push(curr->left);
}
}
vector<int> ancestors;
Node* node = nullptr;
stk.push(root);
// Find the node with the given key
while (!stk.empty()) {
Node* curr = stk.top();
stk.pop();
if (curr->data == key) {
node = curr;
break;
}
if (curr->right) {
stk.push(curr->right);
}
if (curr->left) {
stk.push(curr->left);
}
}
// Collect ancestors
while (parent.find(node) != parent.end()) {
node = parent[node];
ancestors.push_back(node->data);
}
return ancestors;
}
void printArray(vector<int>& arr) {
for (int num : arr) {
cout << num << " ";
}
cout << endl;
}
int main() {
// Constructing the binary tree
// 1
// / \
// 2 3
// / \
// 4 5
// / \
// 7 8
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);
root->left->right->left = new Node(7);
root->left->right->right = new Node(8);
int key = 7;
vector<int> result = printAncestors(root, key);
printArray(result);
return 0;
}
// C Code to print all ancestors of a given key
// in a Binary Tree without Recursion
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* left;
struct Node* right;
};
// Function to create a new node
struct Node* createNode(int x) {
struct Node* newNode
= (struct Node*)malloc(sizeof(struct Node));
newNode->data = x;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// Function to print the array of ancestors
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// Function to find and return ancestors of the given key
void printAncestors(struct Node* root, int key) {
if (!root) {
return;
}
struct Node* parent[1000] = {NULL};
struct Node* stack[1000];
int top = -1;
stack[++top] = root;
// Build parent mapping using iterative DFS
while (top != -1) {
struct Node* curr = stack[top--];
if (curr->right) {
parent[curr->right->data] = curr;
stack[++top] = curr->right;
}
if (curr->left) {
parent[curr->left->data] = curr;
stack[++top] = curr->left;
}
}
struct Node* node = NULL;
stack[++top] = root;
// Find the node with the given key
while (top != -1) {
struct Node* curr = stack[top--];
if (curr->data == key) {
node = curr;
break;
}
if (curr->right) {
stack[++top] = curr->right;
}
if (curr->left) {
stack[++top] = curr->left;
}
}
// Collect ancestors
int ancestors[1000];
int count = 0;
while (node && parent[node->data] != NULL) {
node = parent[node->data];
ancestors[count++] = node->data;
}
// Print ancestors
printArray(ancestors, count);
}
int main() {
// Constructing the binary tree
// 1
// / \
// 2 3
// / \
// 4 5
// / \
// 7 8
struct Node* root = createNode(1);
root->left = createNode(2);
root->right = createNode(3);
root->left->left = createNode(4);
root->left->right = createNode(5);
root->left->right->left = createNode(7);
root->left->right->right = createNode(8);
int key = 7;
printAncestors(root, key);
return 0;
}
// Java Code to print all ancestors of a given key
// in a Binary Tree without Recursion
import java.util.*;
class Node {
int data;
Node left, right;
Node(int x) {
data = x;
left = right = null;
}
}
class GfG {
// Function to find and return ancestors of
// the given key
static int[] printAncestors(Node root, int key) {
if (root == null) {
return new int[0];
}
Map<Node, Node> parent = new HashMap<>();
Stack<Node> stk = new Stack<>();
stk.push(root);
// Build parent mapping using iterative DFS
while (!stk.isEmpty()) {
Node curr = stk.pop();
if (curr.right != null) {
parent.put(curr.right, curr);
stk.push(curr.right);
}
if (curr.left != null) {
parent.put(curr.left, curr);
stk.push(curr.left);
}
}
List<Integer> ancestors = new ArrayList<>();
Node node = null;
stk.push(root);
// Find the node with the given key
while (!stk.isEmpty()) {
Node curr = stk.pop();
if (curr.data == key) {
node = curr;
break;
}
if (curr.right != null) {
stk.push(curr.right);
}
if (curr.left != null) {
stk.push(curr.left);
}
}
// Collect ancestors
while (parent.containsKey(node)) {
node = parent.get(node);
ancestors.add(node.data);
}
return ancestors.stream().mapToInt(i -> i).toArray();
}
static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}
public static void main(String[] args) {
// Constructing the binary tree
// 1
// / \
// 2 3
// / \
// 4 5
// / \
// 7 8
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);
root.left.right.left = new Node(7);
root.left.right.right = new Node(8);
int key = 7;
int[] result = printAncestors(root, key);
printArray(result);
}
}
# Python Code to print all ancestors of a given key
# in a Binary Tree without Recursion
class Node:
def __init__(self, x):
self.data = x
self.left = None
self.right = None
# Function to find and return ancestors
# of the given key
def printAncestors(root, key):
if not root:
return []
parent = {}
stk = [root]
# Build parent mapping using iterative DFS
while stk:
curr = stk.pop()
if curr.right:
parent[curr.right] = curr
stk.append(curr.right)
if curr.left:
parent[curr.left] = curr
stk.append(curr.left)
ancestors = []
node = None
stk.append(root)
# Find the node with the given key
while stk:
curr = stk.pop()
if curr.data == key:
node = curr
break
if curr.right:
stk.append(curr.right)
if curr.left:
stk.append(curr.left)
# Collect ancestors
while node in parent:
node = parent[node]
ancestors.append(node.data)
return ancestors
def printArray(arr):
print(" ".join(map(str, arr)))
if __name__ == "__main__":
# Constructing the binary tree
# 1
# / \
# 2 3
# / \
# 4 5
# / \
# 7 8
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.left.right.left = Node(7)
root.left.right.right = Node(8)
key = 7
result = printAncestors(root, key)
printArray(result)
// C# Code to print all ancestors of a given key
// in a Binary Tree without 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 {
// Function to find and return ancestors of
// the given key
public static int[] printAncestors(Node root, int key) {
if (root == null) {
return new int[0];
}
Dictionary<Node, Node> parent = new Dictionary<Node, Node>();
Stack<Node> stk = new Stack<Node>();
stk.Push(root);
// Build parent mapping using iterative DFS
while (stk.Count > 0) {
Node curr = stk.Pop();
if (curr.right != null) {
parent[curr.right] = curr;
stk.Push(curr.right);
}
if (curr.left != null) {
parent[curr.left] = curr;
stk.Push(curr.left);
}
}
List<int> ancestors = new List<int>();
Node node = null;
stk.Push(root);
// Find the node with the given key
while (stk.Count > 0) {
Node curr = stk.Pop();
if (curr.data == key) {
node = curr;
break;
}
if (curr.right != null) {
stk.Push(curr.right);
}
if (curr.left != null) {
stk.Push(curr.left);
}
}
// Collect ancestors
while (parent.ContainsKey(node)) {
node = parent[node];
ancestors.Add(node.data);
}
return ancestors.ToArray();
}
public static void printArray(int[] arr) {
foreach (int num in arr) {
Console.Write(num + " ");
}
Console.WriteLine();
}
public static void Main() {
// Constructing the binary tree
// 1
// / \
// 2 3
// / \
// 4 5
// / \
// 7 8
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);
root.left.right.left = new Node(7);
root.left.right.right = new Node(8);
int key = 7;
int[] result = printAncestors(root, key);
printArray(result);
}
}
// JavaScript Code to print all ancestors of a given key
// in a Binary Tree without Recursion
class Node {
constructor(x) {
this.data = x;
this.left = null;
this.right = null;
}
}
// Function to find and return ancestors of
// the given key
function printAncestors(root, key) {
if (!root) {
return [];
}
let parent = new Map();
let stk = [];
stk.push(root);
// Build parent mapping using iterative DFS
while (stk.length > 0) {
let curr = stk.pop();
if (curr.right) {
parent.set(curr.right, curr);
stk.push(curr.right);
}
if (curr.left) {
parent.set(curr.left, curr);
stk.push(curr.left);
}
}
let ancestors = [];
let node = null;
stk.push(root);
// Find the node with the given key
while (stk.length > 0) {
let curr = stk.pop();
if (curr.data === key) {
node = curr;
break;
}
if (curr.right) {
stk.push(curr.right);
}
if (curr.left) {
stk.push(curr.left);
}
}
// Collect ancestors
while (parent.has(node)) {
node = parent.get(node);
ancestors.push(node.data);
}
return ancestors;
}
function printArray(arr) {
console.log(arr.join(" "));
}
// Constructing the binary tree
// 1
// / \
// 2 3
// / \
// 4 5
// / \
// 7 8
let 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);
root.left.right.left = new Node(7);
root.left.right.right = new Node(8);
let key = 7;
let result = printAncestors(root, key);
printArray(result);
Output
5 2 1
Time Complexity: O(n) – Tree traversal visits each node once.
Space Complexity: O(n) – Stack and parent map store nodes.