Common nodes in the inorder sequence of a tree between given two nodes in O(1) space

Given a binary tree consisting of distinct values and two numbers K1 and K2, the task is to find all nodes that lie between them in the inorder sequence of the tree.
Examples:

Input:
          1
        /   \
     12    11
     /       /   \
  3    4     13
         \      /
       15   9
k1 = 12
k2 = 15
Output:
1 4
Explanation:
Inorder sequence is 3 12 1 4 15 11 9 13
The common nodes between 12 and 15 in the inorder sequence of the tree are {1, 4}.

Input:
                  5
                /   \
              21    77
             /  \      \
         61   16    36
                  \     /
                10  3
                /
             23
k1 = 23
k2 = 3
Output:
10 5 77
Explanation:
Inorder sequence is 61 21 16 23 10 5 77 3 36
The common nodes between 23 and 3 in the inorder sequence of the tree are {10, 5, 77}.

Approach:
In order to solve this problem, we are using the Morris Inorder Traversal of a Binary Tree to avoid the use of any extra space. We are keeping a flag to set when either of K1 or K2 is found. Once found, print every node that appears in the inorder sequence until the other node is found.

Below is the implementation of the above approach:



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ Program to find
// the common nodes
// between given two nodes
// in the inorder sequence
// of the binary tree
  
#include <bits/stdc++.h>
using namespace std;
  
// Definition of Binary
// Tree Structure
struct tNode {
    int data;
    struct tNode* left;
    struct tNode* right;
};
  
// Helper function to allocate
// memory to create new nodes
struct tNode* newtNode(int data)
{
    struct tNode* node = new tNode;
    node->data = data;
    node->left = NULL;
    node->right = NULL;
  
    return (node);
}
  
// Flag to set if
// either of K1 or
// K2 is found
int flag = 0;
  
// Function to traverse the
// binary tree without recursion
// and without stack using
// Morris Traversal
void findCommonNodes(struct tNode* root,
                     int K1, int K2)
{
    struct tNode *current, *pre;
  
    if (root == NULL)
        return;
  
    current = root;
    while (current != NULL) {
  
        if (current->left == NULL) {
  
            if (current->data == K1 || current->data == K2) {
                if (flag) {
                    return;
                }
                else {
                    flag = 1;
                }
            }
            else if (flag) {
                cout << current->data << " ";
            }
            current = current->right;
        }
        else {
  
            // Find the inorder predecessor
            // of current
            pre = current->left;
            while (pre->right != NULL
                   && pre->right != current)
                pre = pre->right;
  
            // Make current as the right
            // child of its inorder
            // predecessor
            if (pre->right == NULL) {
                pre->right = current;
                current = current->left;
            }
  
            // Revert the changes made
            // to restore the original tree
            // i.e., fix the right child
            // of predecessor
            else {
                pre->right = NULL;
                if (current->data == K1 || current->data == K2) {
                    if (flag) {
                        return;
                    }
                    else {
                        flag = 1;
                    }
                }
                else if (flag) {
                    cout << current->data << " ";
                }
                current = current->right;
            } // End of if condition pre->right == NULL
        } // End of if condition current->left == NULL
    } // End of while
}
  
// Driver code
int main()
{
    struct tNode* root = newtNode(1);
    root->left = newtNode(12);
    root->right = newtNode(11);
    root->left->left = newtNode(3);
    root->right->left = newtNode(4);
    root->right->right = newtNode(13);
    root->right->left->right = newtNode(15);
    root->right->right->left = newtNode(9);
  
    int K1 = 12, K2 = 15;
  
    findCommonNodes(root, K1, K2);
  
    return 0;
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to find the common nodes
// between given two nodes in the inorder 
// sequence of the binary tree
import java.util.*;
  
class GFG{
  
// Definition of Binary Tree 
static class tNode 
{
    int data;
    tNode left;
    tNode right;
};
  
// Helper function to allocate
// memory to create new nodes
static tNode newtNode(int data)
{
    tNode node = new tNode();
    node.data = data;
    node.left = null;
    node.right = null;
  
    return (node);
}
  
// Flag to set if either 
// of K1 or K2 is found
static int flag = 0;
  
// Function to traverse the binary 
// tree without recursion and 
// without stack using 
// Morris Traversal
static void findCommonNodes(tNode root,
                            int K1, int K2)
{
    tNode current, pre;
  
    if (root == null)
        return;
    current = root;
      
    while (current != null)
    {
        if (current.left == null)
        {
            if (current.data == K1 ||
                current.data == K2) 
            {
                if (flag == 1
                {
                    return;
                }
                else
                {
                    flag = 1;
                }
            }
            else if (flag == 1
            {
                System.out.print(current.data + " ");
            }
            current = current.right;
        }
        else 
        {
  
            // Find the inorder predecessor
            // of current
            pre = current.left;
            while (pre.right != null && 
                   pre.right != current)
            {
                pre = pre.right;
            }
  
            // Make current as the right
            // child of its inorder
            // predecessor
            if (pre.right == null)
            {
                pre.right = current;
                current = current.left;
            }
  
            // Revert the changes made
            // to restore the original tree
            // i.e., fix the right child
            // of predecessor
            else
            {
                pre.right = null;
                if (current.data == K1 || 
                    current.data == K2)
                {
                    if (flag == 1)
                    {
                        return;
                    }
                    else
                    {
                        flag = 1;
                    }
                }
                else if (flag == 1)
                {
                    System.out.print(current.data + " ");
                }
                current = current.right;
            } // End of if condition pre.right == null
        } // End of if condition current.left == null
    } // End of while
}
  
// Driver code
public static void main(String[] args)
{
    tNode root = newtNode(1);
    root.left = newtNode(12);
    root.right = newtNode(11);
    root.left.left = newtNode(3);
    root.right.left = newtNode(4);
    root.right.right = newtNode(13);
    root.right.left.right = newtNode(15);
    root.right.right.left = newtNode(9);
  
    int K1 = 12, K2 = 15;
  
    findCommonNodes(root, K1, K2);
}
}
  
// This code is contributed by Amit Katiyar

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to find the common nodes
// between given two nodes in the inorder 
// sequence of the binary tree
using System;
  
class GFG{
  
// Definition of Binary Tree 
class tNode 
{
    public int data;
    public tNode left;
    public tNode right;
};
  
// Helper function to allocate
// memory to create new nodes
static tNode newtNode(int data)
{
    tNode node = new tNode();
    node.data = data;
    node.left = null;
    node.right = null;
  
    return (node);
}
  
// Flag to set if either 
// of K1 or K2 is found
static int flag = 0;
  
// Function to traverse the binary 
// tree without recursion and 
// without stack using 
// Morris Traversal
static void findCommonNodes(tNode root,
                            int K1, int K2)
{
    tNode current, pre;
  
    if (root == null)
        return;
    current = root;
      
    while (current != null)
    {
        if (current.left == null)
        {
            if (current.data == K1 ||
                current.data == K2) 
            {
                if (flag == 1) 
                {
                    return;
                }
                else
                {
                    flag = 1;
                }
            }
            else if (flag == 1) 
            {
                Console.Write(current.data + " ");
            }
            current = current.right;
        }
        else
        {
  
            // Find the inorder predecessor
            // of current
            pre = current.left;
            while (pre.right != null && 
                   pre.right != current)
            {
                pre = pre.right;
            }
  
            // Make current as the right
            // child of its inorder
            // predecessor
            if (pre.right == null)
            {
                pre.right = current;
                current = current.left;
            }
  
            // Revert the changes made
            // to restore the original tree
            // i.e., fix the right child
            // of predecessor
            else
            {
                pre.right = null;
                if (current.data == K1 || 
                    current.data == K2)
                {
                    if (flag == 1)
                    {
                        return;
                    }
                    else
                    {
                        flag = 1;
                    }
                }
                else if (flag == 1)
                {
                    Console.Write(current.data + " ");
                }
                current = current.right;
            } // End of if condition pre.right == null
        } // End of if condition current.left == null
    } // End of while
}
  
// Driver code
public static void Main(String[] args)
{
    tNode root = newtNode(1);
    root.left = newtNode(12);
    root.right = newtNode(11);
    root.left.left = newtNode(3);
    root.right.left = newtNode(4);
    root.right.right = newtNode(13);
    root.right.left.right = newtNode(15);
    root.right.right.left = newtNode(9);
  
    int K1 = 12, K2 = 15;
  
    findCommonNodes(root, K1, K2);
}
}
  
// This code is contributed by Amit Katiyar

chevron_right


Output:

1 4

Time Complexity: O(N)
Auxiliary Space: O(1)

competitive-programming-img




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

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.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : amit143katiyar