Given a binary tree and two nodes. The task is to count the number of turns needs to reach from one node to another node of the Binary tree.
Examples:
Input: Below Binary Tree and two nodes 5 & 6 1 / 2 3 / / 4 5 6 7 / / 8 9 10 Output: Number of Turns needed to reach from 5 to 6: 3 Input: For above tree if two nodes are 1 & 4 Output: Straight line : 0 turn
Idea based on the Lowest Common Ancestor in a Binary Tree
We have to follow the step.
1…Find the LCA of given two node
2…Given node present either on the left side or right side or equal to LCA.
…. According to above condition over program falls under two Case.
Case 1: If none of the nodes is equal to LCA, we get these nodes either on the left side or right side. We call two functions for each node. ....a) if (CountTurn(LCA->right, first, false, &Count) || CountTurn(LCA->left, first, true, &Count)) ; ....b) Same for second node. ....Here Count is used to store number of turns need to reached the target node. Case 2: If one of the nodes is equal to LCA_Node. Then we count only number of turns needs to reached the second node. If LCA == (Either first or second) ....a) if (countTurn(LCA->right, second/first, false, &Count) || countTurn(LCA->left, second/first, true, &Count)) ;
3… Working of CountTurn Function
// we pass turn true if we move
// left subtree and false if we
// move right subTree
CountTurn(LCA, Target_node, count, Turn) // if found the key value in tree if (root->key == key) return true; case 1: If Turn is true that means we are in left_subtree If we going left_subtree then there is no need to increment count else Increment count and set turn as false case 2: if Turn is false that means we are in right_subtree if we going right_subtree then there is no need to increment count else increment count and set turn as true. // if key is not found. return false;
Below the implementation of above idea.
C++
// C++ Program to count number of turns // in a Binary Tree. #include <iostream> using namespace std; // A Binary Tree Node struct Node { struct Node* left, *right; int key; }; // Utility function to create a new // tree Node Node* newNode( int key) { Node* temp = new Node; temp->key = key; temp->left = temp->right = NULL; return temp; } // Utility function to find the LCA of // two given values n1 and n2. struct Node* findLCA( struct Node* root, int n1, int n2) { // Base case if (root == NULL) return NULL; // If either n1 or n2 matches with // root's key, report the presence by // returning root (Note that if a key // is ancestor of other, then the // ancestor key becomes LCA if (root->key == n1 || root->key == n2) return root; // Look for keys in left and right subtrees Node* left_lca = findLCA(root->left, n1, n2); Node* right_lca = findLCA(root->right, n1, n2); // If both of the above calls return // Non-NULL, then one key is present // in once subtree and other is present // in other, So this node is the LCA if (left_lca && right_lca) return root; // Otherwise check if left subtree or right // subtree is LCA return (left_lca != NULL) ? left_lca : right_lca; } // function count number of turn need to reach // given node from it's LCA we have two way to bool CountTurn(Node* root, int key, bool turn, int * count) { if (root == NULL) return false ; // if found the key value in tree if (root->key == key) return true ; // Case 1: if (turn == true ) { if (CountTurn(root->left, key, turn, count)) return true ; if (CountTurn(root->right, key, !turn, count)) { *count += 1; return true ; } } else // Case 2: { if (CountTurn(root->right, key, turn, count)) return true ; if (CountTurn(root->left, key, !turn, count)) { *count += 1; return true ; } } return false ; } // Function to find nodes common to given two nodes int NumberOFTurn( struct Node* root, int first, int second) { struct Node* LCA = findLCA(root, first, second); // there is no path between these two node if (LCA == NULL) return -1; int Count = 0; // case 1: if (LCA->key != first && LCA->key != second) { // count number of turns needs to reached // the second node from LCA if (CountTurn(LCA->right, second, false , &Count) || CountTurn(LCA->left, second, true , &Count)) ; // count number of turns needs to reached // the first node from LCA if (CountTurn(LCA->left, first, true , &Count) || CountTurn(LCA->right, first, false , &Count)) ; return Count + 1; } // case 2: if (LCA->key == first) { // count number of turns needs to reached // the second node from LCA CountTurn(LCA->right, second, false , &Count); CountTurn(LCA->left, second, true , &Count); return Count; } else { // count number of turns needs to reached // the first node from LCA1 CountTurn(LCA->right, first, false , &Count); CountTurn(LCA->left, first, true , &Count); return Count; } } // Driver program to test above functions int main() { // Let us create binary tree given in the above // example Node* root = newNode(1); root->left = newNode(2); root->right = newNode(3); root->left->left = newNode(4); root->left->right = newNode(5); root->right->left = newNode(6); root->right->right = newNode(7); root->left->left->left = newNode(8); root->right->left->left = newNode(9); root->right->left->right = newNode(10); int turn = 0; if ((turn = NumberOFTurn(root, 5, 10))) cout << turn << endl; else cout << "Not Possible" << endl; return 0; } |
Java
//A Java Program to count number of turns //in a Binary Tree. public class Turns_to_reach_another_node { // making Count global such that it can get // modified by different methods static int Count; // A Binary Tree Node static class Node { Node left, right; int key; // Constructor Node( int key) { this .key = key; left = null ; right = null ; } } // Utility function to find the LCA of // two given values n1 and n2. static Node findLCA(Node root, int n1, int n2) { // Base case if (root == null ) return null ; // If either n1 or n2 matches with // root's key, report the presence by // returning root (Note that if a key // is ancestor of other, then the // ancestor key becomes LCA if (root.key == n1 || root.key == n2) return root; // Look for keys in left and right subtrees Node left_lca = findLCA(root.left, n1, n2); Node right_lca = findLCA(root.right, n1, n2); // If both of the above calls return // Non-NULL, then one key is present // in once subtree and other is present // in other, So this node is the LCA if (left_lca != null && right_lca != null ) return root; // Otherwise check if left subtree or right // subtree is LCA return (left_lca != null ) ? left_lca : right_lca; } // function count number of turn need to reach // given node from it's LCA we have two way to static boolean CountTurn(Node root, int key, boolean turn) { if (root == null ) return false ; // if found the key value in tree if (root.key == key) return true ; // Case 1: if (turn == true ) { if (CountTurn(root.left, key, turn)) return true ; if (CountTurn(root.right, key, !turn)) { Count += 1 ; return true ; } } else // Case 2: { if (CountTurn(root.right, key, turn)) return true ; if (CountTurn(root.left, key, !turn)) { Count += 1 ; return true ; } } return false ; } // Function to find nodes common to given two nodes static int NumberOfTurn(Node root, int first, int second) { Node LCA = findLCA(root, first, second); // there is no path between these two node if (LCA == null ) return - 1 ; Count = 0 ; // case 1: if (LCA.key != first && LCA.key != second) { // count number of turns needs to reached // the second node from LCA if (CountTurn(LCA.right, second, false ) || CountTurn(LCA.left, second, true )) ; // count number of turns needs to reached // the first node from LCA if (CountTurn(LCA.left, first, true ) || CountTurn(LCA.right, first, false )) ; return Count + 1 ; } // case 2: if (LCA.key == first) { // count number of turns needs to reached // the second node from LCA CountTurn(LCA.right, second, false ); CountTurn(LCA.left, second, true ); return Count; } else { // count number of turns needs to reached // the first node from LCA1 CountTurn(LCA.right, first, false ); CountTurn(LCA.left, first, true ); return Count; } } // Driver program to test above functions public static void main(String[] args) { // Let us create binary tree given in the above // example 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.right.left = new Node( 6 ); root.right.right = new Node( 7 ); root.left.left.left = new Node( 8 ); root.right.left.left = new Node( 9 ); root.right.left.right = new Node( 10 ); int turn = 0 ; if ((turn = NumberOfTurn(root, 5 , 10 )) != 0 ) System.out.println(turn); else System.out.println( "Not Possible" ); } } // This code is contributed by Sumit Ghosh |
C#
using System; //A C# Program to count number of turns //in a Binary Tree. public class Turns_to_reach_another_node { // making Count global such that it can get // modified by different methods public static int Count; // A Binary Tree Node public class Node { public Node left, right; public int key; // Constructor public Node( int key) { this .key = key; left = null ; right = null ; } } // Utility function to find the LCA of // two given values n1 and n2. public static Node findLCA(Node root, int n1, int n2) { // Base case if (root == null ) { return null ; } // If either n1 or n2 matches with // root's key, report the presence by // returning root (Note that if a key // is ancestor of other, then the // ancestor key becomes LCA if (root.key == n1 || root.key == n2) { return root; } // Look for keys in left and right subtrees Node left_lca = findLCA(root.left, n1, n2); Node right_lca = findLCA(root.right, n1, n2); // If both of the above calls return // Non-NULL, then one key is present // in once subtree and other is present // in other, So this node is the LCA if (left_lca != null && right_lca != null ) { return root; } // Otherwise check if left subtree or right // subtree is LCA return (left_lca != null ) ? left_lca : right_lca; } // function count number of turn need to reach // given node from it's LCA we have two way to public static bool CountTurn(Node root, int key, bool turn) { if (root == null ) { return false ; } // if found the key value in tree if (root.key == key) { return true ; } // Case 1: if (turn == true ) { if (CountTurn(root.left, key, turn)) { return true ; } if (CountTurn(root.right, key, !turn)) { Count += 1; return true ; } } else // Case 2: { if (CountTurn(root.right, key, turn)) { return true ; } if (CountTurn(root.left, key, !turn)) { Count += 1; return true ; } } return false ; } // Function to find nodes common to given two nodes public static int NumberOfTurn(Node root, int first, int second) { Node LCA = findLCA(root, first, second); // there is no path between these two node if (LCA == null ) { return -1; } Count = 0; // case 1: if (LCA.key != first && LCA.key != second) { // count number of turns needs to reached // the second node from LCA if (CountTurn(LCA.right, second, false ) || CountTurn(LCA.left, second, true )) { ; } // count number of turns needs to reached // the first node from LCA if (CountTurn(LCA.left, first, true ) || CountTurn(LCA.right, first, false )) { ; } return Count + 1; } // case 2: if (LCA.key == first) { // count number of turns needs to reached // the second node from LCA CountTurn(LCA.right, second, false ); CountTurn(LCA.left, second, true ); return Count; } else { // count number of turns needs to reached // the first node from LCA1 CountTurn(LCA.right, first, false ); CountTurn(LCA.left, first, true ); return Count; } } // Driver program to test above functions public static void Main( string [] args) { // Let us create binary tree given in the above // example 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.right.left = new Node(6); root.right.right = new Node(7); root.left.left.left = new Node(8); root.right.left.left = new Node(9); root.right.left.right = new Node(10); int turn = 0; if ((turn = NumberOfTurn(root, 5, 10)) != 0) { Console.WriteLine(turn); } else { Console.WriteLine( "Not Possible" ); } } } // This code is contributed by Shrikant13 |
Output:
4
Time Complexity : O(n)
Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above.
leave a comment
0 Comments