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 anecestor[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++
/* C++ program to calculate Kth ancestor of given node */ #include <iostream> #include <queue> using namespace std; // A Binary Tree Node struct Node { int data; struct Node *left, *right; }; // fucntion to generate array of ancestors void generateArray(Node *root, int ancestors[]) { // There will be no ancestor of root node ancestors[root->data] = -1; // level order traversal to // generate 1st ancestor 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); } } } // function to calculate Kth ancestor int kthAncestor(Node *root, int n, int k, int node) { // create array to store 1st ancestors int ancestors[n+1] = {0}; // generate first ancestor array generateArray(root,ancestors); // variable to track record of number of // ancestors visited int count = 0; while (node!=-1) { node = ancestors[node]; count++; if (count==k) break ; } // print Kth ancestor return node; } // Utility function to create a new tree node Node* newNode( int data) { Node *temp = new Node; temp->data = data; temp->left = temp->right = NULL; return temp; } // Driver program to test above functions int main() { // Let us create binary tree shown in above diagram 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; // print kth ancestor of given node cout<<kthAncestor(root,5,k,node); return 0; } |
Java
/* Java program to calculate Kth ancestor of given node */ import java.util.*; class GfG { // A Binary Tree Node static class Node { int data; Node left, right; } // fucntion to generate array of ancestors static void generateArray(Node root, int ancestors[]) { // There will be no ancestor of root node ancestors[root.data] = - 1 ; // level order traversal to // generate 1st ancestor 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); } } } // function to calculate Kth ancestor static int kthAncestor(Node root, int n, int k, int node) { // create array to store 1st ancestors int ancestors[] = new int [n + 1 ]; // generate first ancestor array generateArray(root,ancestors); // variable to track record of number of // ancestors visited int count = 0 ; while (node!=- 1 ) { node = ancestors[node]; count++; if (count==k) break ; } // print Kth ancestor return node; } // Utility function to create a new tree node static Node newNode( int data) { Node temp = new Node(); temp.data = data; temp.left = null ; temp.right = null ; return temp; } // Driver program to test above functions public static void main(String[] args) { // Let us create binary tree shown in above diagram 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 ; // print kth ancestor of given node System.out.println(kthAncestor(root, 5 ,k,node)); } } |
Python3
"""Python3 program to calculate Kth ancestor of given node """ # A Binary Tree Node # Utility function to create a new tree node class newNode: # Constructor to create a newNode def __init__( self , data): self .data = data self .left = None self .right = None # fucntion to generate array of ancestors def generateArray(root, ancestors): # There will be no ancestor of root node ancestors[root.data] = - 1 # level order traversal to # generate 1st ancestor 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) # function to calculate Kth ancestor def kthAncestor(root, n, k, node): # create array to store 1st ancestors ancestors = [ 0 ] * (n + 1 ) # generate first ancestor array generateArray(root,ancestors) # variable to track record of number # of ancestors visited count = 0 while (node ! = - 1 ) : node = ancestors[node] count + = 1 if (count = = k): break # prKth ancestor return node # Driver Code if __name__ = = '__main__' : # Let us create binary tree shown # in above diagram 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 # prkth ancestor of given node print (kthAncestor(root, 5 , k, node)) # This code is contributed by # SHUBHAMSINGH10 |
C#
/* C# program to calculate Kth ancestor of given node */ using System; using System.Collections.Generic; class GfG { // A Binary Tree Node public class Node { public int data; public Node left, right; } // fucntion to generate array of ancestors static void generateArray(Node root, int []ancestors) { // There will be no ancestor of root node ancestors[root.data] = -1; // level order traversal to // generate 1st ancestor 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); } } } // function to calculate Kth ancestor static int kthAncestor(Node root, int n, int k, int node) { // create array to store 1st ancestors int []ancestors = new int [n + 1]; // generate first ancestor array generateArray(root,ancestors); // variable to track record of number of // ancestors visited int count = 0; while (node != -1) { node = ancestors[node]; count++; if (count == k) break ; } // print Kth ancestor return node; } // Utility function to create a new tree node static Node newNode( int data) { Node temp = new Node(); temp.data = data; temp.left = null ; temp.right = null ; return temp; } // Driver program to test above functions public static void Main(String[] args) { // Let us create binary tree shown in above diagram 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; // print kth ancestor of given node Console.WriteLine(kthAncestor(root,5,k,node)); } } // This code has been contributed by 29AjayKumar |
Output:
1
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.
C++14
// C++ program for finding // kth ancestor of a particular node #include<bits/stdc++.h> using namespace std; // Structure for a node struct node{ int data; struct node *left, *right; node( int x) { data = x; left = right = NULL; } }; // Program to find kth ancestor bool ancestor( struct node* root, int item, int &k) { if (root == NULL) return false ; // Element whose ancestor is to be searched if (root->data == item) { //reduce count by 1 k = k-1; return true ; } else { // Checking in left side bool flag = ancestor(root->left,item,k); if (flag) { if (k == 0) { // If count = 0 i.e. element is found cout<< "[" <<root->data<< "] " ; return false ; } // if count !=0 i.e. this is not the // ancestor we are searching for // so decrement count k = k-1; return true ; } // Similarly Checking in right side bool flag2 = ancestor(root->right,item,k); if (flag2) { if (k == 0) { cout<< "[" <<root->data<< "] " ; return false ; } k = k-1; return true ; } } } // Driver Code 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; } // This code is contributed by Sanjeev Yadav. |
Python3
# Python3 program for finding # kth ancestor of a particular node # Structure for a node class node: def __init__( self , data): self .left = None self .right = None self .data = data # Program to find kth ancestor def ancestor(root, item): global k if (root = = None ): return False # Element whose ancestor is # to be searched if (root.data = = item): # Reduce count by 1 k = k - 1 return True else : # Checking in left side flag = ancestor(root.left, item); if (flag): if (k = = 0 ): # If count = 0 i.e. element is found print ( "[" + str (root.data) + "]" , end = ' ' ) return False # If count !=0 i.e. this is not the # ancestor we are searching for # so decrement count k = k - 1 return True # Similarly Checking in right side flag2 = ancestor(root.right, item) if (flag2): if (k = = 0 ): print ( "[" + str (root.data) + "]" ) return False k = k - 1 return True # Driver code 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) + "]" ) # This code is contributed by rutvik_56 |
[4] is the 1th ancestor of [3]
This article is contributed by Harsh Agarwal. If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.
Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.