Given a binary tree in which nodes are numbered from 1 to n. Given a node and a positive integer K. We have to print the K-th ancestor of the given node in the binary tree. If there does not exist any such ancestor then print -1.
For example in the below given binary tree, 2nd ancestor of node 4 and 5 is 1. 3rd ancestor of node 4 will be -1.

The idea to do this is to first traverse the binary tree and store the ancestor of each node in an array of size n. For example, suppose the array is ancestor[n]. Then at index i, ancestor[i] will store the ancestor of ith node. So, the 2nd ancestor of ith node will be ancestor[ancestor[i]] and so on. We will use this idea to calculate the kth ancestor of the given node. We can use level order traversal to populate this array of ancestors.
Below is the implementation of above idea.
C++
#include <iostream>
#include <queue>
using namespace std;
struct Node
{
int data;
struct Node *left, *right;
};
void generateArray(Node *root, int ancestors[])
{
ancestors[root->data] = -1;
queue<Node*> q;
q.push(root);
while (!q.empty())
{
Node* temp = q.front();
q.pop();
if (temp->left)
{
ancestors[temp->left->data] = temp->data;
q.push(temp->left);
}
if (temp->right)
{
ancestors[temp->right->data] = temp->data;
q.push(temp->right);
}
}
}
int kthAncestor(Node *root, int n, int k, int node)
{
int ancestors[n+1] = {0};
generateArray(root,ancestors);
int count = 0;
while (node!=-1)
{
node = ancestors[node];
count++;
if (count==k)
break ;
}
return node;
}
Node* newNode( int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
int main()
{
Node *root = newNode(1);
root->left = newNode(2);
root->right = newNode(3);
root->left->left = newNode(4);
root->left->right = newNode(5);
int k = 2;
int node = 5;
cout<<kthAncestor(root,5,k,node);
return 0;
}
|
Java
import java.util.*;
class GfG {
static class Node
{
int data;
Node left, right;
}
static void generateArray(Node root, int ancestors[])
{
ancestors[root.data] = - 1 ;
Queue<Node> q = new LinkedList<Node> ();
q.add(root);
while (!q.isEmpty())
{
Node temp = q.peek();
q.remove();
if (temp.left != null )
{
ancestors[temp.left.data] = temp.data;
q.add(temp.left);
}
if (temp.right != null )
{
ancestors[temp.right.data] = temp.data;
q.add(temp.right);
}
}
}
static int kthAncestor(Node root, int n, int k, int node)
{
int ancestors[] = new int [n + 1 ];
generateArray(root,ancestors);
int count = 0 ;
while (node!=- 1 )
{
node = ancestors[node];
count++;
if (count==k)
break ;
}
return node;
}
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.left = null ;
temp.right = null ;
return temp;
}
public static void main(String[] args)
{
Node root = newNode( 1 );
root.left = newNode( 2 );
root.right = newNode( 3 );
root.left.left = newNode( 4 );
root.left.right = newNode( 5 );
int k = 2 ;
int node = 5 ;
System.out.println(kthAncestor(root, 5 ,k,node));
}
}
|
Python3
class newNode:
def __init__( self , data):
self .data = data
self .left = None
self .right = None
def generateArray(root, ancestors):
ancestors[root.data] = - 1
q = []
q.append(root)
while ( len (q)):
temp = q[ 0 ]
q.pop( 0 )
if (temp.left):
ancestors[temp.left.data] = temp.data
q.append(temp.left)
if (temp.right):
ancestors[temp.right.data] = temp.data
q.append(temp.right)
def kthAncestor(root, n, k, node):
ancestors = [ 0 ] * (n + 1 )
generateArray(root,ancestors)
count = 0
while (node ! = - 1 ) :
node = ancestors[node]
count + = 1
if (count = = k):
break
return node
if __name__ = = '__main__' :
root = newNode( 1 )
root.left = newNode( 2 )
root.right = newNode( 3 )
root.left.left = newNode( 4 )
root.left.right = newNode( 5 )
k = 2
node = 5
print (kthAncestor(root, 5 , k, node))
|
C#
using System;
using System.Collections.Generic;
class GfG
{
public class Node
{
public int data;
public Node left, right;
}
static void generateArray(Node root, int []ancestors)
{
ancestors[root.data] = -1;
LinkedList<Node> q = new LinkedList<Node> ();
q.AddLast(root);
while (q.Count != 0)
{
Node temp = q.First.Value;
q.RemoveFirst();
if (temp.left != null )
{
ancestors[temp.left.data] = temp.data;
q.AddLast(temp.left);
}
if (temp.right != null )
{
ancestors[temp.right.data] = temp.data;
q.AddLast(temp.right);
}
}
}
static int kthAncestor(Node root, int n, int k, int node)
{
int []ancestors = new int [n + 1];
generateArray(root,ancestors);
int count = 0;
while (node != -1)
{
node = ancestors[node];
count++;
if (count == k)
break ;
}
return node;
}
static Node newNode( int data)
{
Node temp = new Node();
temp.data = data;
temp.left = null ;
temp.right = null ;
return temp;
}
public static void Main(String[] args)
{
Node root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(5);
int k = 2;
int node = 5;
Console.WriteLine(kthAncestor(root,5,k,node));
}
}
|
Javascript
<script>
class Node
{
constructor()
{
this .data = 0;
this .left = null ;
this .right = null ;
}
}
function generateArray(root, ancestors)
{
ancestors[root.data] = -1;
var q = [];
q.push(root);
while (q.length != 0)
{
var temp = q[0];
q.shift();
if (temp.left != null )
{
ancestors[temp.left.data] = temp.data;
q.push(temp.left);
}
if (temp.right != null )
{
ancestors[temp.right.data] = temp.data;
q.push(temp.right);
}
}
}
function kthAncestor(root, n, k, node)
{
var ancestors = Array(n+1).fill(0);
generateArray(root,ancestors);
var count = 0;
while (node != -1)
{
node = ancestors[node];
count++;
if (count == k)
break ;
}
return node;
}
function newNode(data)
{
var temp = new Node();
temp.data = data;
temp.left = null ;
temp.right = null ;
return temp;
}
var root = newNode(1);
root.left = newNode(2);
root.right = newNode(3);
root.left.left = newNode(4);
root.left.right = newNode(5);
var k = 2;
var node = 5;
document.write(kthAncestor(root,5,k,node));
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(n)
Method 2: In this method first we will get an element whose ancestor has to be searched and from that node, we will decrement count one by one till we reach that ancestor node.
for example –
consider the tree given below:-
(1)
/ \
(4) (2)
/ \ \
(3) (7) (6)
\
(8)
Then check if k=0 if yes then return that element as an ancestor else climb a level up and reduce k (k = k-1).
Initially k = 2
First we search for 8 then,
at 8 => check if(k == 0) but k = 2 so k = k-1 => k = 2-1 = 1 and climb a level up i.e. at 7
at 7 => check if(k == 0) but k = 1 so k = k-1 => k = 1-1 = 0 and climb a level up i.e. at 4
at 4 => check if(k == 0) yes k = 0 return this node as ancestor.
Implementation:
C++14
#include<bits/stdc++.h>
using namespace std;
struct node{
int data;
struct node *left, *right;
node( int x)
{
data = x;
left = right = NULL;
}
};
bool ancestor( struct node* root, int item, int &k)
{
if (root == NULL)
return false ;
if (root->data == item)
{
k = k-1;
return true ;
}
else
{
bool flag = ancestor(root->left,item,k);
if (flag)
{
if (k == 0)
{
cout<< "[" <<root->data<< "] " ;
return false ;
}
k = k-1;
return true ;
}
bool flag2 = ancestor(root->right,item,k);
if (flag2)
{
if (k == 0)
{
cout<< "[" <<root->data<< "] " ;
return false ;
}
k = k-1;
return true ;
}
}
}
int main()
{
struct node* root = new node(1);
root->left = new node(4);
root->left->right = new node(7);
root->left->left = new node(3);
root->left->right->left = new node(8);
root->right = new node(2);
root->right->right = new node(6);
int item,k;
item = 3;
k = 1;
int loc = k;
bool flag = ancestor(root,item,k);
if (flag)
cout<< "Ancestor doesn't exist\n" ;
else
cout<< "is the " <<loc<< "th ancestor of [" <<
item<< "]" <<endl;
return 0;
}
|
Java
import java.io.*;
class Node
{
int data;
Node left, right;
Node( int x)
{
this .data = x;
this .left = this .right = null ;
}
}
class GFG{
static int k = 1 ;
static boolean ancestor(Node root, int item)
{
if (root == null )
return false ;
if (root.data == item)
{
k = k- 1 ;
return true ;
}
else
{
boolean flag = ancestor(root.left, item);
if (flag)
{
if (k == 0 )
{
System.out.print( "[" + root.data + "] " );
return false ;
}
k = k - 1 ;
return true ;
}
boolean flag2 = ancestor(root.right, item);
if (flag2)
{
if (k == 0 )
{
System.out.print( "[" + root.data + "] " );
return false ;
}
k = k - 1 ;
return true ;
}
}
return false ;
}
public static void main(String[] args)
{
Node root = new Node( 1 );
root.left = new Node( 4 );
root.left.right = new Node( 7 );
root.left.left = new Node( 3 );
root.left.right.left = new Node( 8 );
root.right = new Node( 2 );
root.right.right = new Node( 6 );
int item = 3 ;
int loc = k;
boolean flag = ancestor(root, item);
if (flag)
System.out.println( "Ancestor doesn't exist" );
else
System.out.println( "is the " + (loc) +
"th ancestor of [" +
(item) + "]" );
}
}
|
Python3
class node:
def __init__( self , data):
self .left = None
self .right = None
self .data = data
def ancestor(root, item):
global k
if (root = = None ):
return False
if (root.data = = item):
k = k - 1
return True
else :
flag = ancestor(root.left, item);
if (flag):
if (k = = 0 ):
print ( "[" + str (root.data) + "]" , end = ' ' )
return False
k = k - 1
return True
flag2 = ancestor(root.right, item)
if (flag2):
if (k = = 0 ):
print ( "[" + str (root.data) + "]" )
return False
k = k - 1
return True
if __name__ = = "__main__" :
root = node( 1 )
root.left = node( 4 )
root.left.right = node( 7 )
root.left.left = node( 3 )
root.left.right.left = node( 8 )
root.right = node( 2 )
root.right.right = node( 6 )
item = 3
k = 1
loc = k
flag = ancestor(root, item)
if (flag):
print ( "Ancestor doesn't exist" )
else :
print ( "is the " + str (loc) +
"th ancestor of [" + str (item) + "]" )
|
C#
using System;
public class Node
{
public int data;
public Node left, right;
public Node( int x)
{
this .data = x;
this .left = this .right = null ;
}
}
class GFG{
static int k = 1;
static bool ancestor(Node root, int item)
{
if (root == null )
return false ;
if (root.data == item)
{
k = k - 1;
return true ;
}
else
{
bool flag = ancestor(root.left, item);
if (flag)
{
if (k == 0)
{
Console.Write( "[" + root.data + "] " );
return false ;
}
k = k - 1;
return true ;
}
bool flag2 = ancestor(root.right, item);
if (flag2)
{
if (k == 0)
{
Console.Write( "[" + root.data + "] " );
return false ;
}
k = k - 1;
return true ;
}
}
return false ;
}
static public void Main()
{
Node root = new Node(1);
root.left = new Node(4);
root.left.right = new Node(7);
root.left.left = new Node(3);
root.left.right.left = new Node(8);
root.right = new Node(2);
root.right.right = new Node(6);
int item = 3;
int loc = k;
bool flag = ancestor(root, item);
if (flag)
Console.WriteLine( "Ancestor doesn't exist" );
else
Console.WriteLine( "is the " + (loc) +
"th ancestor of [" +
(item) + "]" );
}
}
|
Javascript
<script>
class Node
{
constructor(x)
{
this .data=x;
this .left = this .right = null ;
}
}
function ancestor(root, item)
{
if (root == null )
{
return false ;
}
if (root.data == item)
{
k = k - 1;
return true ;
}
else
{
let flag = ancestor(root.left, item);
if (flag)
{
if (k == 0)
{
document.write( "[" + (root.data) + "] " );
return false ;
}
k = k - 1;
return true ;
}
let flag2 = ancestor(root.right, item);
if (flag2)
{
if (k == 0)
{
document.write( "[" + (root.data) + "] " );
return false ;
}
k = k - 1;
return true ;
}
}
}
let root = new Node(1)
root.left = new Node(4)
root.left.right = new Node(7)
root.left.left = new Node(3)
root.left.right.left = new Node(8)
root.right = new Node(2)
root.right.right = new Node(6)
let item = 3
let k = 1
let loc = k
let flag = ancestor(root, item)
if (flag)
document.write( "Ancestor doesn't exist" )
else
document.write( "is the " + (loc) +
"th ancestor of [" + (item) + "]" )
</script>
|
Output
[4] is the 1th ancestor of [3]
Time Complexity: O(n)
Auxiliary Space: O(n)
This article is contributed by Harsh Agarwal. If you like GeeksforGeeks and would like to contribute, you can also write an article using write.geeksforgeeks.org or mail your article to review-team@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Please Login to comment...