Open In App

Find value K in given Complete Binary Tree with values indexed from 1 to N

Last Updated : 27 Mar, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

Given a complete binary tree with values indexed from 1 to N and a key K. The task is to check whether a key exists in the tree or not. Print “true” if the key exists, otherwise print “false”. 

Complete Binary Tree: A Binary Tree is a complete Binary Tree if all the levels are completely filled except possibly the last level and the last level has all keys as left as possible 

Examples: 

Input: K = 2 

         1
       /   \  
     2      3  
    /  \   / \
   4    5 6   7
 /  \   /
8    9 10

Output: true 
 

Input: K = 11 

         1
       /   \  
     2      3  
    /  \   / \
   4    5 6   7
 /  \   /
8    9 10

Output: false 

Naive Approach: The simplest approach would be to simply traverse the entire tree and check if the key exists in the tree or not.

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

Efficient Approach: The approach is based on the idea that the tree is a complete binary tree and the nodes are indexed from 1 to N starting from the top. So we can track down the path going from the root to the key if at all the key existed. Below are the steps:

  1. For a complete binary tree given node i, its children will be 2*i and 2*i + 1. Therefore, given node i, its parent node will be i/2.
  2. Iteratively find out the parent of the key until the root node of the tree is found, and store the steps in an array steps[] as -1 for left and 1 for right (Left means that the current node is the left child of its parent and right means the current node is the right child of its parent).
  3. Now transverse the tree according to the moves stored in the array steps[]. If the entire array is successfully transversed, it means that the key exists in the tree so print “True”, otherwise print “False”.

 Below is the implementation of the above approach: 

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Class containing left
// and right child of current node
// and key value
class Node {
  public:
    int data;
    Node* left;
    Node* right;
  
    Node(int item)
    {
        data = item;
        left = NULL;
        right = NULL;
    }
};
 
// Function to store the
// list of the directions
vector<int> findSteps(Node* root, int data)
{
    vector<int> steps;
     
    // While the root is not found
    while (data != 1) {
        // If it is the right
        // child of its parent
        if (data / 2.0 > data / 2) {
 
            // Add right step (1)
            steps.push_back(1);
        }
        else {
 
            // Add left step (-1)
            steps.push_back(-1);
        }
 
        int parent = data / 2;
 
        // Repeat the same
        // for its parent
        data = parent;
    }
 
    // Reverse the steps list
    reverse(steps.begin(), steps.end());
 
    // Return the steps
    return steps;
}
 
// Function to find
// if the key is present or not
bool findKey(Node* root, int data)
{
    // Get the steps to be followed
    vector<int> steps = findSteps(root, data);
     
    // Taking one step at a time
    for (auto cur_step : steps)
    {
            // Go left
            if (cur_step == -1) {
  
                // If left child does
                // not exist return false
                if (root->left == NULL)
                    return false;
  
                root = root->left;
            }
             
            // Go right
            else {
  
                // If right child does
                // not exist return false
                if (root->right == NULL)
                    return false;
  
                root = root->right;
            }
        }
  
        // If the entire array of steps
        // has been successfully
        // traversed
        return true;
}
 
 
 
int main()
{
    /* Consider the following complete binary tree
                 1
                / \
               2   3
              / \ / \
             4  5 6  7
            / \ /
           8  9 10
    */
    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->left->left->right = new Node(9);
    root->left->right->left = new Node(10);
     
    // Function Call
    cout<<boolalpha<<findKey(root, 7)<<endl;
}
 
// This code is contributed by Pushpesh Raj.


Java




// Java program for the above approach
import java.util.*;
import java.io.*;
 
// Class containing left
// and right child of current node
// and key value
class Node {
    int data;
    Node left, right;
 
    public Node(int item)
    {
        data = item;
        left = null;
        right = null;
    }
}
 
class Solution {
 
    // Function to store the
    // list of the directions
    public static ArrayList<Integer>
    findSteps(Node root, int data)
    {
        ArrayList<Integer> steps
            = new ArrayList<Integer>();
 
        // While the root is not found
        while (data != 1) {
            // If it is the right
            // child of its parent
            if (data / 2.0 > data / 2) {
 
                // Add right step (1)
                steps.add(1);
            }
            else {
 
                // Add left step (-1)
                steps.add(-1);
            }
 
            int parent = data / 2;
 
            // Repeat the same
            // for its parent
            data = parent;
        }
 
        // Reverse the steps list
        Collections.reverse(steps);
 
        // Return the steps
        return steps;
    }
 
    // Function to find
    // if the key is present or not
    public static boolean
    findKey(Node root, int data)
    {
        // Get the steps to be followed
        ArrayList<Integer> steps
            = findSteps(root, data);
 
        // Taking one step at a time
        for (Integer cur_step : steps) {
 
            // Go left
            if (cur_step == -1) {
 
                // If left child does
                // not exist return false
                if (root.left == null)
                    return false;
 
                root = root.left;
            }
 
            // Go right
            else {
 
                // If right child does
                // not exist return false
                if (root.right == null)
                    return false;
 
                root = root.right;
            }
        }
 
        // If the entire array of steps
        // has been successfully
        // traversed
        return true;
    }
 
    public static void main(String[] args)
    {
        /* Consider the following complete binary tree
                 1
                / \ 
               2   3 
              / \ / \
             4  5 6  7
            / \ /
           8  9 10 
        */
        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.left.left.right = new Node(9);
        root.left.right.left = new Node(10);
 
        // Function Call
        System.out.println(findKey(root, 7));
    }
}


Python3




# Python program to implement above approach
 
# Class containing left
# and right child of current node
# and key value
class Node:
    def __init__(self,item):
     
        self.data = item
        self.left = None
        self.right = None
     
 
# Function to store the
# list of the directions
 
def findSteps(root,data):
    steps = []
 
    # While the root is not found
    while (data != 1):
     
        # If it is the right
        # child of its parent
        if (data / 2 > data // 2):
 
            # Add right step (1)
            steps.append(1)
        else:
 
            # Add left step (-1)
            steps.append(-1)
 
        parent = data // 2
 
        # Repeat the same
        # for its parent
        data = parent
 
    # Reverse the steps list
    steps = steps[::-1]
 
    # Return the steps
    return steps
 
# Function to find
# if the key is present or not
 
def findKey(root,data):
 
    # Get the steps to be followed
    steps = findSteps(root, data)
 
    # Taking one step at a time
    for cur_step in steps:
 
        # Go left
        if (cur_step == -1):
 
            # If left child does
            # not exist return False
            if (root.left == None):
                return False
 
            root = root.left
 
        # Go right
        else:
 
            # If right child does
            # not exist return False
            if (root.right == None):
                return False
 
            root = root.right
 
    # If the entire array of steps
    # has been successfully
    # traversed
    return True
 
# driver code
 
#  Consider the following complete binary tree
#                 1
#                 / \
#             2 3
#             / \ / \
#             4 5 6 7
#             / \ /
#         8 9 10
#        
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
root.left.left.left = Node(8)
root.left.left.right = Node(9)
root.left.right.left = Node(10)
 
# Function Call
print(findKey(root, 7))
 
# This code is contributed by shinjanpatra


C#




// C# program for the above approach
using System;
using System.Collections.Generic;
 
// Class containing left
// and right child of current node
// and key value
class Node
{
    public int data;
    public Node left, right;
  
    public Node(int item)
    {
        data = item;
        left = right = null;
    }
}
 
class Solution {
 
    // Function to store the
    // list of the directions
    public static List<int>
    findSteps(Node root, int data)
    {
        List<int> steps
            = new List<int>();
 
        // While the root is not found
        while (data != 1) {
            // If it is the right
            // child of its parent
            if (data / 2.0 > data / 2) {
 
                // Add right step (1)
                steps.Add(1);
            }
            else {
 
                // Add left step (-1)
                steps.Add(-1);
            }
 
            int parent = data / 2;
 
            // Repeat the same
            // for its parent
            data = parent;
        }
 
        // Reverse the steps list
        steps.Reverse();
 
        // Return the steps
        return steps;
    }
 
    // Function to find
    // if the key is present or not
    public static bool
    findKey(Node root, int data)
    {
        // Get the steps to be followed
        List<int> steps
            = findSteps(root, data);
 
        // Taking one step at a time
        foreach (int cur_step in steps) {
 
            // Go left
            if (cur_step == -1) {
 
                // If left child does
                // not exist return false
                if (root.left == null)
                    return false;
 
                root = root.left;
            }
 
            // Go right
            else {
 
                // If right child does
                // not exist return false
                if (root.right == null)
                    return false;
 
                root = root.right;
            }
        }
 
        // If the entire array of steps
        // has been successfully
        // traversed
        return true;
    }
 
    public static void Main()
    {
        /* Consider the following complete binary tree
                 1
                / \ 
               2   3 
              / \ / \
             4  5 6  7
            / \ /
           8  9 10 
        */
        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.left.left.right = new Node(9);
        root.left.right.left = new Node(10);
 
        // Function Call
        Console.Write(findKey(root, 7));
    }
}


Javascript




<script>
 
// JavaScript program to implement above approach
 
// Class containing left
// and right child of current node
// and key value
class Node {
    constructor(item)
    {
        this.data = item;
        this.left = null;
        this.right = null;
    }
}
 
// Function to store the
// list of the directions
 
function findSteps(root,data)
{
    let steps = [];
 
    // While the root is not found
    while (data != 1)
    {
     
        // If it is the right
        // child of its parent
        if (data / 2 > Math.floor(data / 2)) {
 
            // Add right step (1)
            steps.push(1);
        }
        else {
 
            // Add left step (-1)
            steps.push(-1);
        }
 
        let parent = Math.floor(data / 2);
 
        // Repeat the same
        // for its parent
        data = parent;
    }
 
    // Reverse the steps list
    steps.reverse();
 
    // Return the steps
    return steps;
}
 
// Function to find
// if the key is present or not
 
function findKey(root,data)
{
        // Get the steps to be followed
    let steps = findSteps(root, data);
 
    // Taking one step at a time
    for (let cur_step of steps) {
 
        // Go left
        if (cur_step == -1) {
 
            // If left child does
            // not exist return false
            if (root.left == null)
                return false;
 
            root = root.left;
        }
 
        // Go right
        else {
 
            // If right child does
            // not exist return false
            if (root.right == null)
                return false;
 
            root = root.right;
        }
    }
 
    // If the entire array of steps
    // has been successfully
    // traversed
    return true;
}
 
// driver code
 
/* Consider the following complete binary tree
                1
                / \
            2 3
            / \ / \
            4 5 6 7
            / \ /
        8 9 10
        */
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.right.left = new Node(6);
root.right.right = new Node(7);
root.left.left.left = new Node(8);
root.left.left.right = new Node(9);
root.left.right.left = new Node(10);
 
// Function Call
document.write(findKey(root, 7),"</br>");
 
// This code is contributed by shinjanpatra
 
</script>


Output: 

true

 

Time Complexity: O(logN) 
Auxiliary Space: O(logN)



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads