Check whether BST contains Dead End or not
Last Updated :
12 Apr, 2024
Given a Binary search Tree that contains positive integer values greater than 0. The task is to check whether the BST contains a dead end or not. Here Dead End means, we are not able to insert any element after that node.
Examples:
Input : 8
/ \
5 9
/ \
2 7
/
1
Output : Yes
Explanation : Node "1" is the dead End because
after that we cant insert any element.
Input : 8
/ \
7 10
/ / \
2 9 13
Output : Yes
Explanation : We can't insert any element at
node 9.
If we take a closer look at the problem, we can notice that we basically need to check if there is a leaf node with value x such that x+1 and x-1 exist in BST with the exception of x = 1. For x = 1, we can’t insert 0 as the problem statement says BST contains positive integers only.
To implement the above idea we first traverse the whole BST and store all nodes in a set. We also store all leaves in a separate hash to avoid re-traversal of BST. Finally, we check for every leaf node x, if x-1 and x+1 are present in set or not.
Below is a C++ implementation of the above idea.
C++
#include<bits/stdc++.h>
using namespace std;
// A BST node
struct Node
{
int data;
struct Node *left, *right;
};
// A utility function to create a new node
Node *newNode(int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
/* A utility function to insert a new Node
with given key in BST */
struct Node* insert(struct Node* node, int key)
{
/* If the tree is empty, return a new Node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->data)
node->left = insert(node->left, key);
else if (key > node->data)
node->right = insert(node->right, key);
/* return the (unchanged) Node pointer */
return node;
}
// Returns true if there is a dead end in tree,
// else false.
bool isDeadEndUtil(Node *root, int low, int high) {
// Base case
if (root == NULL)
return false;
// Check if current node falls within the range
if (root->data >= low && root->data <= high)
return true;
// Recur for left and right subtrees
return isDeadEndUtil(root->left, low, root->data - 1) || isDeadEndUtil(root->right, root->data + 1, high);
}
bool isDeadEnd(Node *root) {
return isDeadEndUtil(root, 1, INT_MAX);
}
// Driver program
int main()
{
Node *root = NULL;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if (isDeadEnd(root) == true)
cout << "Yes " << endl;
else
cout << "No " << endl;
return 0;
}
Java
// Java program check whether BST contains
// dead end or not
import java.util.*;
class Main {
// create two empty hash sets that store all
// BST elements and leaf nodes respectively.
static HashSet<Integer> all_nodes
= new HashSet<Integer>();
static HashSet<Integer> leaf_nodes
= new HashSet<Integer>();
/* A utility function to insert a new Node
with given key in BST */
public static Node insert(Node node, int key)
{
/* If the tree is empty, return a new Node */
if (node == null)
return new Node(key);
/* Otherwise, recur down the tree */
if (key < node.data)
node.left = insert(node.left, key);
else if (key > node.data)
node.right = insert(node.right, key);
/* return the Node */
return node;
}
// Function to store all node of given binary search
// tree
public static void storeNodes(Node root)
{
if (root == null)
return;
// store all node of binary search tree
all_nodes.add(root.data);
// store leaf node in leaf_hash
if (root.left == null && root.right == null) {
leaf_nodes.add(root.data);
return;
}
// recur call rest tree
storeNodes(root.left);
storeNodes(root.right);
}
// Returns true if there is a dead end in tree,
// else false.
public static boolean isDeadEnd(Node root)
{
// Base case
if (root == null)
return false;
// insert 0 in 'all_nodes' for handle case
// if bst contain value 1
all_nodes.add(0);
// Call storeNodes function to store all BST Node
storeNodes(root);
// Traversal leaf node and check Tree contain
// continuous sequence of
// size tree or Not
for (int i : leaf_nodes) {
int x = i;
// Here we check first and last element of
// continuous sequence that are x-1 & x+1
if (all_nodes.contains(x + 1)
&& all_nodes.contains(x - 1)) {
return true;
}
}
return false;
}
// Driver program
public static void main(String[] args)
{
/* 8
/ \
5 11
/ \
2 7
\
3
\
4 */
Node root = null;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if (isDeadEnd(root) == true)
System.out.println("Yes");
else
System.out.println("No");
}
}
// A BST node
class Node {
int data;
Node left, right;
Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
// This code is contributed by Tapesh(tapeshdua420)
Python3
# Python 3 program check
# whether BST contains
# dead end or not
all_nodes = set()
leaf_nodes = set()
# A BST node
class newNode:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
''' A utility function to
insert a new Node with
given key in BST '''
def insert(node, key):
'''/* If the tree is empty,
return a new Node */ '''
if (node == None):
return newNode(key)
# Otherwise, recur down
# the tree
if (key < node.data):
node.left = insert(node.left,
key)
elif (key > node.data):
node.right = insert(node.right,
key)
# return the (unchanged)
# Node pointer
return node
# Function to store all node
# of given binary search tree
def storeNodes(root):
global all_nodes
global leaf_nodes
if (root == None):
return
# store all node of binary
# search tree
all_nodes.add(root.data)
# store leaf node in leaf_hash
if (root.left == None and
root.right == None):
leaf_nodes.add(root.data)
return
# recur call rest tree
storeNodes(root. left)
storeNodes(root.right)
# Returns true if there is
# a dead end in tree,
# else false.
def isDeadEnd(root):
global all_nodes
global leaf_nodes
# Base case
if (root == None):
return False
# create two empty hash
# sets that store all BST
# elements and leaf nodes
# respectively.
# insert 0 in 'all_nodes'
# for handle case if bst
# contain value 1
all_nodes.add(0)
# Call storeNodes function
# to store all BST Node
storeNodes(root)
# Traversal leaf node and
# check Tree contain
# continuous sequence of
# size tree or Not
for x in leaf_nodes:
# Here we check first and
# last element of continuous
# sequence that are x-1 & x+1
if ((x + 1) in all_nodes and
(x - 1) in all_nodes):
return True
return False
# Driver code
if __name__ == '__main__':
'''/* 8
/ \
5 11
/ \
2 7
\
3
\
4 */
'''
root = None
root = insert(root, 8)
root = insert(root, 5)
root = insert(root, 2)
root = insert(root, 3)
root = insert(root, 7)
root = insert(root, 11)
root = insert(root, 4)
if(isDeadEnd(root) == True):
print("Yes")
else:
print("No")
# This code is contributed by bgangwar59
C#
// C# code for the above approach
using System;
using System.Collections.Generic;
// A BST node
public class Node {
public int data;
public Node left, right;
public Node(int data)
{
this.data = data;
left = null;
right = null;
}
}
public class GFG {
// create two empty hash sets that store all
// BST elements and leaf nodes respectively.
static HashSet<int> all_nodes = new HashSet<int>();
static HashSet<int> leaf_nodes = new HashSet<int>();
/* A utility function to insert a new Node
with given key in BST */
public static Node insert(Node node, int key)
{
/* If the tree is empty, return a new Node */
if (node == null)
return new Node(key);
/* Otherwise, recur down the tree */
if (key < node.data)
node.left = insert(node.left, key);
else if (key > node.data)
node.right = insert(node.right, key);
/* return the Node */
return node;
}
// Function to store all node of given binary search
// tree
public static void storeNodes(Node root)
{
if (root == null)
return;
// store all node of binary search tree
all_nodes.Add(root.data);
// store leaf node in leaf_hash
if (root.left == null && root.right == null) {
leaf_nodes.Add(root.data);
return;
}
// recur call rest tree
storeNodes(root.left);
storeNodes(root.right);
}
// Returns true if there is a dead end in tree,
// else false.
public static bool isDeadEnd(Node root)
{
// Base case
if (root == null)
return false;
// insert 0 in 'all_nodes' for handle case
// if bst contain value 1
all_nodes.Add(0);
// Call storeNodes function to store all BST Node
storeNodes(root);
// Traversal leaf node and check Tree contain
// continuous sequence of
// size tree or Not
foreach(int i in leaf_nodes)
{
int x = i;
// Here we check first and last element of
// continuous sequence that are x-1 & x+1
if (all_nodes.Contains(x + 1)
&& all_nodes.Contains(x - 1)) {
return true;
}
}
return false;
}
static public void Main()
{
// Code
/* 8
/ \
5 11
/ \
2 7
\
3
\
4 */
Node root = null;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if (isDeadEnd(root) == true)
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed by lokesh.
Javascript
class Node {
constructor(data) {
this.data = data;
this.left = null;
this.right = null;
}
}
// A utility function to create a new node
function newNode(data) {
let temp = new Node(data);
return temp;
}
/* A utility function to insert a new Node
with given key in BST */
function insert(node, key) {
/* If the tree is empty, return a new Node */
if (node == null) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node.data) {
node.left = insert(node.left, key);
} else if (key > node.data) {
node.right = insert(node.right, key);
}
/* return the (unchanged) Node pointer */
return node;
}
// Function to store all node of given binary search tree
function storeNodes(root, all_nodes, leaf_nodes) {
if (root == null) return;
// store all node of binary search tree
all_nodes.add(root.data);
// store leaf node in leaf_nodes
if (root.left == null && root.right == null) {
leaf_nodes.add(root.data);
return;
}
// recur call rest tree
storeNodes(root.left, all_nodes, leaf_nodes);
storeNodes(root.right, all_nodes, leaf_nodes);
}
// Returns true if there is a dead end in tree,
// else false.
function isDeadEnd(root) {
// Base case
if (root == null) return false;
// create two empty sets that store all
// BST elements and leaf nodes respectively.
let all_nodes = new Set();
let leaf_nodes = new Set();
// insert 0 in 'all_nodes' for handle case
// if bst contain value 1
all_nodes.add(0);
// Call storeNodes function to store all BST Node
storeNodes(root, all_nodes, leaf_nodes);
// Traversal leaf node and check Tree contain
// continuous sequence of
// size tree or Not
for (let i of leaf_nodes) {
let x = i;
// Here we check first and last element of
// continuous sequence that are x-1 & x+1
if (all_nodes.has(x + 1) && all_nodes.has(x - 1)) return true;
}
return false;
}
// Driver program
/* 8
/ \
5 11
/ \
2 7
\
3
\
4 */
let root = null;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if (isDeadEnd(root) == true) {
console.log("Yes");
} else {
console.log("No");
}
// This code is contributed by lokeshpotta20.
Time Complexity : O(n)
The time complexity of the above algorithm is O(n) as we are traversing the entire tree to check for the dead end.
Space complexity: O(n)
The space complexity of the above algorithm is O(n) as we need to store all the elements in the unordered_set which is of size n.
Improved Approach
In the above approach we are using 2 hashmaps , one for storing all nodes and one for storing leaf nodes , instead of using 2 maps we can do this problem with 1 hashmap also .
We can pass the hashmap of all nodes and check if for node x there exists a x-1 and x+1 or not. If we got a node for which x+1 and x-1 both are present we will return true otherwise we will return false
Implementation:
C++
// C++ program check whether BST contains
// dead end or not
#include<bits/stdc++.h>
using namespace std;
// A BST node
struct Node
{
int data;
struct Node *left, *right;
};
// A utility function to create a new node
Node *newNode(int data)
{
Node *temp = new Node;
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}
/* A utility function to insert a new Node
with given key in BST */
struct Node* insert(struct Node* node, int key)
{
/* If the tree is empty, return a new Node */
if (node == NULL) return newNode(key);
/* Otherwise, recur down the tree */
if (key < node->data)
node->left = insert(node->left, key);
else if (key > node->data)
node->right = insert(node->right, key);
/* return the (unchanged) Node pointer */
return node;
}
void findallNodes(Node* root,map<int,int> &allnodes)
{
if(root == NULL)
return ;
allnodes[root->data] = 1;
findallNodes(root->left,allnodes);
findallNodes(root->right,allnodes);
}
bool check(Node* root,map<int,int> &allnodes)
{
if(root == NULL)
return false;
if(root->left == NULL and root->right == NULL)
{
int pre = root->data - 1;
int next = root->data + 1;
if(allnodes.find(pre) != allnodes.end() and allnodes.find(next) != allnodes.end())
return true;
}
return check(root->left,allnodes) or check(root->right,allnodes);
}
bool isDeadEnd(Node *root)
{
// Base case
if (root == NULL)
return false ;
map<int,int> allnodes;
// adding 0 for handling the exception of node having data = 1
allnodes[0] = 1;
findallNodes(root,allnodes);
return check(root,allnodes);
}
// Driver program
int main()
{
/* 8
/ \
5 11
/ \
2 7
\
3
\
4 */
Node *root = NULL;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if (isDeadEnd(root) == true)
cout << "Yes " << endl;
else
cout << "No " << endl;
return 0;
}
Java
// Java program check whether BST contains dead end or not
import java.io.*;
import java.util.*;
// A BST node
class Node {
int data;
Node left, right;
Node(int data)
{
this.data = data;
left = right = null;
}
}
class GFG {
Node root;
void BST() { root = null; }
// A utility function to insert a new Node with given
// key in BST
Node insert(Node node, int key)
{
// If the tree is empty, return a new node
if (node == null) {
return new Node(key);
}
// Otherwise, recur down the tree
if (key < node.data) {
node.left = insert(node.left, key);
}
else if (key > node.data) {
node.right = insert(node.right, key);
}
// return the (unchanged) Node pointer
return node;
}
void findAllNodes(Node root,
Map<Integer, Integer> allNodes)
{
if (root == null) {
return;
}
allNodes.put(root.data, 1);
findAllNodes(root.left, allNodes);
findAllNodes(root.right, allNodes);
}
boolean check(Node root, Map<Integer, Integer> allNodes)
{
if (root == null) {
return false;
}
if (root.left == null && root.right == null) {
int pre = root.data - 1;
int next = root.data + 1;
if (allNodes.containsKey(pre)
&& allNodes.containsKey(next)) {
return true;
}
}
return check(root.left, allNodes)
|| check(root.right, allNodes);
}
boolean isDeadEnd(Node root)
{
// Base case
if (root == null) {
return false;
}
Map<Integer, Integer> allNodes
= new HashMap<Integer, Integer>();
// adding 0 for handling the exception of node
// having date = 1
allNodes.put(0, 1);
findAllNodes(root, allNodes);
return check(root, allNodes);
}
public static void main(String[] args)
{
/*
8
/ \
5 11
/ \
2 7
\
3
\
4 */
GFG tree = new GFG();
Node root = null;
root = tree.insert(root, 8);
root = tree.insert(root, 5);
root = tree.insert(root, 2);
root = tree.insert(root, 3);
root = tree.insert(root, 7);
root = tree.insert(root, 11);
root = tree.insert(root, 4);
if (tree.isDeadEnd(root) == true) {
System.out.println("Yes");
}
else {
System.out.println("No");
}
}
}
// This code is contributed by lokeshmvs21.
Python
# Python program check whether BST contains
# dead end or not
# A BST node
class Node:
def __init__(self, data):
self.data = data
self.left = None
self.right = None
# a utility function to create a new node
def newNode(data):
return Node(data)
# a utility function to insert a new node
# with given key in BST
def insert(node, key):
# if the tree is empty, return a new node
if(node is None):
return newNode(key)
# otherwise , recur down the tree
if(key < node.data):
node.left = insert(node.left, key)
elif(key > node.data):
node.right = insert(node.right, key)
# return the (unchanged) Node pointer
return node
allnodes = {}
def findallNodes(root):
if(root is None):
return
allnodes[root.data] = 1
findallNodes(root.left)
findallNodes(root.right)
def check(root):
if(root is None):
return False
if(root.left is None and root.right is None):
pre = root.data - 1
next = root.data + 1
if(allnodes.get(pre) is not None and allnodes.get(next) is not None):
return True
return check(root.left) or check(root.right)
def isDeadEnd(root):
if(root is None):
return False
allnodes[0] = 1
findallNodes(root)
return check(root)
# driver program
root = None
root = insert(root, 8)
root = insert(root, 5)
root = insert(root, 2)
root = insert(root, 3)
root = insert(root, 7)
root = insert(root, 11)
root = insert(root, 4)
if(isDeadEnd(root) is True):
print("Yes")
else:
print("No")
# THIS CODE IS CONTRIBUTED BY KIRTI AGARWAL(KIRTIAGARWAL23121999)
C#
// C# program check whether BST contains
// dead end or not
using System;
using System.Linq;
using System.Collections.Generic;
class GFG
{
// Structure of a Query
class Node {
public int data;
public Node left, right;
public Node(int data)
{
this.data=data;
this.left=left;
this.right=right;
}
}
/* A utility function to insert a new Node
with given key in BST */
static Node insert(Node node, int key)
{
/* If the tree is empty, return a new Node */
if (node == null)
return new Node(key);
/* Otherwise, recur down the tree */
if (key < node.data)
node.left = insert(node.left, key);
else if (key > node.data)
node.right = insert(node.right, key);
/* return the (unchanged) Node pointer */
return node;
}
static void findallNodes(Node root,Dictionary<int,int> allnodes)
{
if(root == null)
return ;
allnodes.Add(root.data, 1);
findallNodes(root.left,allnodes);
findallNodes(root.right,allnodes);
}
static bool check(Node root,Dictionary<int,int> allnodes)
{
if(root == null)
return false;
if(root.left == null && root.right == null)
{
int pre = root.data - 1;
int next = root.data + 1;
if(allnodes.ContainsKey(pre) ==true && allnodes.ContainsKey(next) ==true)
return true;
}
return check(root.left,allnodes) || check(root.right,allnodes);
}
static bool isDeadEnd(Node root)
{
// Base case
if (root == null)
return false ;
Dictionary<int,int> allnodes=new Dictionary<int, int>();
// adding 0 for handling the exception of node having data = 1
allnodes.Add(0,1);
findallNodes(root,allnodes);
return check(root,allnodes);
}
// Driver program
static public void Main()
{
/* 8
/ \
5 11
/ \
2 7
\
3
\
4 */
Node root = null;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if (isDeadEnd(root) == true)
Console.Write("Yes ");
else
Console.Write("No ");
}
}
Javascript
// JavaScript program to check whether BST contains
// dead end or not
class Node{
constructor(data){
this.data = data;
this.left = null;
this.right = null;
}
}
// A utility function to create a new node
function newNode(data){
let temp = new Node(data);
return temp;
}
// A utility functiion to insert a new node
// with given key in BST
function insert(node, key){
// If the tree is empty, return a new node
if(node == null) return newNode(key);
// Otherwise, recur down the tree
if(key < node.data)
node.left = insert(node.left, key);
else if(key > node.data)
node.right = insert(node.right, key);
// return the (unchanged) Node pointer
return node;
}
let allnodes = new Map();
function findallNodes(root){
if(root == null) return;
allnodes.set(root.data, 1);
findallNodes(root.left);
findallNodes(root.right);
}
function check(root){
if(root == null) return false;
if(root.left == null && root.right == null){
let pre = root.data - 1;
let next = root.data + 1;
if(allnodes.has(pre) != false && allnodes.has(next) != false){
return true;
}
}
return check(root.left) || check(root.right);
}
function isDeadEnd(root){
// Base Case
if(root == null)
return false;
allnodes.set(0,1);
findallNodes(root);
return check(root);
}
// Driver Program
/* 8
/ \
5 11
/ \
2 7
\
3
\
4
*/
let root = null;
root = insert(root, 8);
root = insert(root, 5);
root = insert(root, 2);
root = insert(root, 3);
root = insert(root, 7);
root = insert(root, 11);
root = insert(root, 4);
if(isDeadEnd(root) == true){
console.log("Yes");
}else{
console.log("No");
}
// This code is contributed by Yash Agarwal(yashagarwal2852002)
Time Complexity: O(N) where N is the Number of nodes in a given binary tree.
Auxiliary Space: O(N)
Simple Recursive solution to check whether BST contains dead End
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...