[Approach - 1] Using Specified range of Min and Max Values
The idea is to validate a Binary Search Tree (BST) by maintaining a valid range (−∞, +∞) for every node. Initially, the root node can hold any value within this full range. As we traverse the tree, we narrow the range for each subtree:
For the left subtree, the upper bound becomes the current node’s value (since all left nodes must be smaller).
For the right subtree, the lower bound becomes the current node’s value (since all right nodes must be larger).
If every node’s value falls within its respective valid range, the tree satisfies the BST property and is therefore considered a valid BST.
C++
//Driver Code Starts#include<iostream>#include<climits>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};//Driver Code Ends// Helper function to check if a tree is BST within a given rangeboolisBSTUtil(Node*node,intmin,intmax){if(node==nullptr)returntrue;// If the current node's data // is not in the valid range, return falseif(node->data<min||node->data>max)returnfalse;// Recursively check the left and // right subtrees with updated rangesreturnisBSTUtil(node->left,min,node->data-1)&&isBSTUtil(node->right,node->data+1,max);}// Function to check if the entire binary tree is a BSTboolisBST(Node*root){returnisBSTUtil(root,INT_MIN,INT_MAX);}//Driver Code Startsintmain(){// Create a sample binary tree// 10// / \ // 5 20// / \ // 9 25Node*root=newNode(10);root->left=newNode(5);root->right=newNode(20);root->right->left=newNode(9);root->right->right=newNode(25);if(isBST(root))cout<<"true"<<endl;elsecout<<"false"<<endl;return0;}//Driver Code Ends
C
//Driver Code Starts#include<stdio.h>#include<limits.h>#include<stdbool.h>/// Node structurestructNode{intdata;structNode*left;structNode*right;};//Driver Code Ends// Helper function to check if a tree is BST within a given rangeboolisBSTUtil(structNode*node,intmin,intmax){if(node==NULL)returntrue;// If the current node's data // is not in the valid range, return falseif(node->data<min||node->data>max)returnfalse;// Recursively check the left and // right subtrees with updated rangesreturnisBSTUtil(node->left,min,node->data-1)&&isBSTUtil(node->right,node->data+1,max);}// Function to check if the entire binary tree is a BSTboolisBST(structNode*root){returnisBSTUtil(root,INT_MIN,INT_MAX);}//Driver Code StartsstructNode*createNode(intvalue){structNode*newNode=(structNode*)malloc(sizeof(structNode));newNode->data=value;newNode->left=newNode->right=NULL;returnnewNode;}intmain(){// Create a sample binary tree// 10// / \ // 5 20// / \ // 9 25structNode*root=createNode(10);root->left=createNode(5);root->right=createNode(20);root->right->left=createNode(9);root->right->right=createNode(25);if(isBST(root))printf("true");elseprintf("false");return0;}//Driver Code Ends
Java
//Driver Code Starts// Node structureclassNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{//Driver Code Ends// Helper function to check if a tree is BST within a given rangestaticbooleanisBSTUtil(Nodenode,intmin,intmax){if(node==null)returntrue;// If the current node's data // is not in the valid range, // return falseif(node.data<min||node.data>max)returnfalse;// Recursively check the left and // right subtrees with updated rangesreturnisBSTUtil(node.left,min,node.data-1)&&isBSTUtil(node.right,node.data+1,max);}// Function to check if the entire binary tree is a BSTstaticbooleanisBST(Noderoot){returnisBSTUtil(root,Integer.MIN_VALUE,Integer.MAX_VALUE);}//Driver Code Startspublicstaticvoidmain(String[]args){// Create a sample binary tree// 10// / \// 5 20// / \// 9 25Noderoot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){System.out.println("true");}else{System.out.println("false");}}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None#Driver Code Ends# Helper function to check if a tree is# BST within a given rangedefisBstUtil(node,min_val,max_val):ifnodeisNone:returnTrue# If the current node's data # is not in the valid range, return falseifnode.data<min_valornode.data>max_val:returnFalse# Recursively check the left and # right subtrees with updated rangesreturn(isBstUtil(node.left,min_val,node.data-1)andisBstUtil(node.right,node.data+1,max_val))# Function to check if the entire binary tree is a BSTdefisBST(root):returnisBstUtil(root,float('-inf'),float('inf'))#Driver Code Startsif__name__=="__main__":# Create a sample binary tree# 10# / \# 5 20# / \# 9 25root=Node(10)root.left=Node(5)root.right=Node(20)root.right.left=Node(9)root.right.right=Node(25)ifisBST(root):print("true")else:print("false")#Driver Code Ends
C#
//Driver Code StartsusingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{//Driver Code Ends// Helper function to check if a tree is BST within a given rangestaticboolisBSTUtil(Nodenode,intmin,intmax){if(node==null)returntrue;// If the current node's data // is not in the valid range, return falseif(node.data<min||node.data>max)returnfalse;// Recursively check the left and // right subtrees with updated rangesreturnisBSTUtil(node.left,min,node.data-1)&&isBSTUtil(node.right,node.data+1,max);}// Function to check if the entire binary tree is a BSTstaticboolisBST(Noderoot){returnisBSTUtil(root,int.MinValue,int.MaxValue);}//Driver Code StartsstaticvoidMain(){// Create a sample binary tree// 10// / \// 5 20// / \// 9 25Noderoot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){Console.WriteLine("true");}else{Console.WriteLine("false");}}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(value){this.data=value;this.left=this.right=null;}}//Driver Code Ends// Helper function to check if a tree is BST // within a given rangefunctionisBSTUtil(node,min,max){if(node===null)returntrue;// If the current node's data // is not in the valid range, return falseif(node.data<min||node.data>max)returnfalse;// Recursively check the left and // right subtrees with updated rangesreturnisBSTUtil(node.left,min,node.data-1)&&isBSTUtil(node.right,node.data+1,max);}// Function to check if the entire binary tree is a BSTfunctionisBST(root){returnisBSTUtil(root,-Infinity,Infinity);}//Driver Code Starts// Driver Code// Create a sample binary tree// 10// / \// 5 20// / \// 9 25constroot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){console.log("true");}else{console.log("false");}//Driver Code Ends
Output
false
Time Complexity: O(n), where n is the number of nodes, as each node is visited once. Auxiliary Space: O(h), where h is the height of the tree, due to recursive calls (worst case O(n) for a skewed tree, O(log n) for a balanced tree).
[Approach - 2] Using Inorder Traversal
The idea is to use inorder traversal of a binary search tree, in which the output values are sorted in ascending order. After generating the inorder traversal of the given binary tree, we can check if the values are sorted or not.
Note: We can avoid the use of an Auxiliary Array. While doing In-Order traversal, we can keep track of previously visited value. If the value of the currently visited node is less than the previous value, then the tree is not BST.
C++
//Driver Code Starts#include<iostream>#include<climits>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};//Driver Code Ends// Recursive Function for inorder traversalboolinorder(Node*root,int&prev){if(!root)returntrue;// Recursively check the left subtreeif(!inorder(root->left,prev))returnfalse;// Check the current node value // against the previous valueif(prev>=root->data)returnfalse;prev=root->data;// Recursively check the right subtreereturninorder(root->right,prev);}// Function to check if the entire binary tree is a BSTboolisBST(Node*root){intprev=INT_MIN;returninorder(root,prev);}//Driver Code Startsintmain(){// Create a sample binary tree// 10// / \ // 5 20// / \ // 9 25Node*root=newNode(10);root->left=newNode(5);root->right=newNode(20);root->right->left=newNode(9);root->right->right=newNode(25);if(isBST(root))cout<<"true"<<endl;elsecout<<"false"<<endl;return0;}//Driver Code Ends
C
//Driver Code Starts#include<stdio.h>#include<stdlib.h>#include<limits.h>// Definition for a binary tree nodestructNode{intdata;structNode*left;structNode*right;};//Driver Code Ends// Recursive Function for inorder traversalintisValidBST(structNode*root,int*prev){if(root==NULL)return1;// Recursively check the left subtreeif(!isValidBST(root->left,prev))return0;// Check the current node value// against the previous valueif(*prev>=root->data)return0;*prev=root->data;// Recursively check the right subtreereturnisValidBST(root->right,prev);}// Function to check if the entire binary tree is a BSTintisBST(structNode*root){intprev=INT_MIN;returnisValidBST(root,&prev);}//Driver Code StartsstructNode*createNode(intvalue){structNode*node=(structNode*)malloc(sizeof(structNode));node->data=value;node->left=NULL;node->right=NULL;returnnode;}intmain(){// Create a sample binary tree// 10// / \ // 5 20// / \ // 9 25structNode*root=createNode(10);root->left=createNode(5);root->right=createNode(20);root->right->left=createNode(9);root->right->right=createNode(25);if(isBST(root))printf("true");elseprintf("false");return0;}//Driver Code Ends
Java
//Driver Code Starts// Node structureclassNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{//Driver Code Ends// Recursive Function for inorder traversalstaticbooleaninorder(Noderoot,int[]prev){if(root==null)returntrue;// Recursively check the left subtreeif(!inorder(root.left,prev))returnfalse;// Check the current node value // against the previous valueif(prev[0]>=root.data)returnfalse;prev[0]=root.data;// Recursively check the right subtreereturninorder(root.right,prev);}// Function to check if the entire binary tree is a BSTstaticbooleanisBST(Noderoot){int[]prev={Integer.MIN_VALUE};returninorder(root,prev);}//Driver Code Startspublicstaticvoidmain(String[]args){// Create a sample binary tree// 10// / \// 5 20// / \// 9 25Noderoot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){System.out.println("true");}else{System.out.println("false");}}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None#Driver Code Ends# Recursive Function for inorder traversaldefinorder(root,prev):ifrootisNone:returnTrue# Recursively check the left subtreeifnotinorder(root.left,prev):returnFalse# Check the current node value # against the previous valueifprev[0]>=root.data:returnFalseprev[0]=root.data# Recursively check the right subtreereturninorder(root.right,prev)# Function to check if the entire binary tree is a BSTdefisBST(root):prev=[float('-inf')]returninorder(root,prev)#Driver Code Startsif__name__=="__main__":# Create a sample binary tree# 10# / \# 5 20# / \# 9 25root=Node(10)root.left=Node(5)root.right=Node(20)root.right.left=Node(9)root.right.right=Node(25)ifisBST(root):print("true")else:print("false")#Driver Code Ends
C#
//Driver Code StartsusingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{//Driver Code Ends// Recursive Function for inorder traversalstaticboolinorder(Noderoot,refintprev){if(root==null)returntrue;// Recursively check the left subtreeif(!inorder(root.left,refprev))returnfalse;// Check the current node value // against the previous valueif(prev>=root.data)returnfalse;prev=root.data;// Recursively check the right subtreereturninorder(root.right,refprev);}// Function to check if the entire binary tree is a BSTstaticboolisBST(Noderoot){intprev=int.MinValue;returninorder(root,refprev);}//Driver Code StartsstaticvoidMain(){// Create a sample binary tree// 10// / \// 5 20// / \// 9 25Noderoot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){Console.WriteLine("true");}else{Console.WriteLine("false");}}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(value){this.data=value;this.left=null;this.right=null;}}//Driver Code Ends// Recursive Function for inorder traversalfunctioninorder(root,prev){if(root===null)returntrue;// Recursively check the left subtreeif(!inorder(root.left,prev))returnfalse;// Check the current node value // against the previous valueif(prev[0]>=root.data)returnfalse;prev[0]=root.data;// Recursively check the right subtreereturninorder(root.right,prev);}// Function to check if the entire binary tree is a BSTfunctionisBST(root){letprev=[-Infinity];returninorder(root,prev);}//Driver Code Starts// Driver Code// Create a sample binary tree// 10// / \// 5 20// / \// 9 25constroot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){console.log("true");}else{console.log("false");}//Driver Code Ends
Output
false
Time Complexity: O(n), where n is the number of nodes, as each node is visited once in inorder traversal. Auxiliary Space: O(h), where h is the height of the tree, due to recursive calls (worst case O(n) for a skewed tree, O(log n) for a balanced tree).
[Approach - 3] Using Morris Traversal - O(n) Time and O(1) Space
The idea is to use Morris Traversal for checking if a binary tree is a Binary Search Tree (BST) without using extra space for storing the inorder traversal.
C++
//Driver Code Starts#include<iostream>#include<climits>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};//Driver Code Ends// Function to check if the binary tree // is a BST using Morris TraversalboolisBST(Node*root){Node*curr=root;Node*pre=nullptr;intprevValue=INT_MIN;while(curr!=nullptr){if(curr->left==nullptr){if(curr->data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr->data;curr=curr->right;}else{// Find the inorder predecessor of currpre=curr->left;while(pre->right!=nullptr&&pre->right!=curr){pre=pre->right;}if(pre->right==nullptr){// Create a temporary // thread to the curr nodepre->right=curr;curr=curr->left;}else{pre->right=nullptr;if(curr->data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr->data;curr=curr->right;}}}returntrue;}//Driver Code Startsintmain(){// Create a sample binary tree// 10// / \ // 5 20// / \ // 9 25Node*root=newNode(10);root->left=newNode(5);root->right=newNode(20);root->right->left=newNode(9);root->right->right=newNode(25);if(isBST(root))cout<<"true"<<endl;elsecout<<"false"<<endl;return0;}//Driver Code Ends
C
//Driver Code Starts#include<stdio.h>#include<stdlib.h>#include<limits.h>// Node StructurestructNode{intdata;structNode*left;structNode*right;//Driver Code Ends};// Function to check if the binary tree // is a BST using Morris TraversalintisBST(structNode*root){structNode*curr=root;structNode*pre;intprevValue=INT_MIN;while(curr!=NULL){if(curr->left==NULL){if(curr->data<=prevValue){// Not in ascending orderreturn0;}prevValue=curr->data;curr=curr->right;}else{// Find the inorder predecessor of currpre=curr->left;while(pre->right!=NULL&&pre->right!=curr){pre=pre->right;}if(pre->right==NULL){// Create a temporary // thread to the curr nodepre->right=curr;curr=curr->left;}else{pre->right=NULL;if(curr->data<=prevValue){// Not in ascending orderreturn0;}prevValue=curr->data;curr=curr->right;}}}return1;}//Driver Code StartsstructNode*createNode(intvalue){structNode*newNode=(structNode*)malloc(sizeof(structNode));newNode->data=value;newNode->left=newNode->right=NULL;returnnewNode;}intmain(){// Create a sample binary tree// 10// / \ // 5 20// / \ // 9 25structNode*root=createNode(10);root->left=createNode(5);root->right=createNode(20);root->right->left=createNode(9);root->right->right=createNode(25);if(isBST(root))printf("true");elseprintf("false");return0;}//Driver Code Ends
Java
//Driver Code Starts// Node structureclassNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{//Driver Code Ends// Function to check if the binary tree // is a BST using Morris TraversalstaticbooleanisBST(Noderoot){Nodecurr=root;Nodepre;intprevValue=Integer.MIN_VALUE;while(curr!=null){if(curr.left==null){if(curr.data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr.data;curr=curr.right;}else{// Find the inorder predecessor of currpre=curr.left;while(pre.right!=null&&pre.right!=curr){pre=pre.right;}if(pre.right==null){// Create a temporary thread // to the curr nodepre.right=curr;curr=curr.left;}else{pre.right=null;if(curr.data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr.data;curr=curr.right;}}}returntrue;}//Driver Code Startspublicstaticvoidmain(String[]args){// Create a sample binary tree// 10// / \// 5 20// / \// 9 25Noderoot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){System.out.println("true");}else{System.out.println("false");}}}//Driver Code Ends
Python
#Driver Code Starts# Node structureclassNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None#Driver Code Ends# Function to check if the binary tree # is a BST using Morris TraversaldefisBST(root):curr=rootprevValue=float('-inf')whilecurr:ifcurr.leftisNone:ifcurr.data<=prevValue:# Not in ascending orderreturnFalseprevValue=curr.datacurr=curr.rightelse:# Find the inorder predecessor of currpre=curr.leftwhilepre.rightandpre.right!=curr:pre=pre.rightifpre.rightisNone:# Create a temporary # thread to the curr nodepre.right=currcurr=curr.leftelse:pre.right=Noneifcurr.data<=prevValue:# Not in ascending orderreturnFalseprevValue=curr.datacurr=curr.rightreturnTrue#Driver Code Startsif__name__=="__main__":# Create a sample binary tree# 10# / \# 5 20# / \# 9 25root=Node(10)root.left=Node(5)root.right=Node(20)root.right.left=Node(9)root.right.right=Node(25)ifisBST(root):print("true")else:print("false")#Driver Code Ends
C#
//Driver Code StartsusingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{//Driver Code Ends// Function to check if the binary tree // is a BST using Morris TraversalstaticboolisBST(Noderoot){Nodecurr=root;Nodepre;intprevValue=int.MinValue;while(curr!=null){if(curr.left==null){if(curr.data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr.data;curr=curr.right;}else{// Find the inorder predecessor of currpre=curr.left;while(pre.right!=null&&pre.right!=curr){pre=pre.right;}if(pre.right==null){// Create a temporary // thread to the curr nodepre.right=curr;curr=curr.left;}else{pre.right=null;if(curr.data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr.data;curr=curr.right;}}}returntrue;}//Driver Code StartsstaticvoidMain(){// Create a sample binary tree// 10// / \// 5 20// / \// 9 25Noderoot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){Console.WriteLine("true");}else{Console.WriteLine("false");}}}//Driver Code Ends
JavaScript
//Driver Code Starts// Node structureclassNode{constructor(value){this.data=value;this.left=null;this.right=null;}}//Driver Code Ends// Function to check if the binary tree // is a BST using Morris TraversalfunctionisBST(root){letcurr=root;letprevValue=-Infinity;while(curr!==null){if(curr.left===null){if(curr.data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr.data;curr=curr.right;}else{// Find the inorder predecessor of currletpre=curr.left;while(pre.right!==null&&pre.right!==curr){pre=pre.right;}if(pre.right===null){// Create a temporary// thread to the curr nodepre.right=curr;curr=curr.left;}else{pre.right=null;if(curr.data<=prevValue){// Not in ascending orderreturnfalse;}prevValue=curr.data;curr=curr.right;}}}returntrue;}//Driver Code Starts// Driver Code// Create a sample binary tree// 10// / \// 5 20// / \// 9 25constroot=newNode(10);root.left=newNode(5);root.right=newNode(20);root.right.left=newNode(9);root.right.right=newNode(25);if(isBST(root)){console.log("true");}else{console.log("false");}//Driver Code Ends