Given the root of a binary tree, check whether it is a Binary Search Tree (BST) or not. A binary tree is considered a BST if it satisfies the following properties:
All nodes in the left subtree of a node have values less than the node's value.
All nodes in the right subtree of a node have values greater than the node's value.
Both the left and right subtrees are also Binary Search Trees.
Return true if the given binary tree is a BST; otherwise, return false.
Examples:
Input:
Output: false Explanation: In the right subtree of node 10, all values must be greater than 10, but 9 < 10. Hence, the tree is not a BST.
Output: true Explanation: Every node satisfies the BST property. Hence, the given binary tree is a valid BST.
Using Specified range of Min and Max Values - O(n) Time and O(h) Space
The idea is to maintain a valid range (min, max) for every node. Initially, the root node can have any value within the range (-∞, +∞). While traversing the tree, update the valid range for each subtree. For the left subtree, the upper bound becomes the current node's value, and for the right subtree, the lower bound becomes the current node's value. If any node lies outside its valid range, the tree is not a BST. If all nodes satisfy their respective ranges, the binary tree is a valid BST.
C++
#include<iostream>#include<climits>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// 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);}intmain(){// 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;}
C
#include<stdio.h>#include<limits.h>#include<stdbool.h>/// Node structurestructNode{intdata;structNode*left;structNode*right;};// 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);}structNode*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;}
Java
// Node structureclassNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{// 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);}publicstaticvoidmain(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");}}}
Python
# Node structureclassNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# 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'))if__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")
C#
usingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// 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);}staticvoidMain(){// 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");}}}
JavaScript
// Node structureclassNode{constructor(value){this.data=value;this.left=this.right=null;}}// 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// 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");}
Output
false
Using Inorder Traversal - O(n) Time and O(h) Space
The idea is based on the property that the inorder traversal of a Binary Search Tree (BST) always visits nodes in strictly increasing order. Perform an inorder traversal of the given binary tree while keeping track of the previously visited node. If the value of the current node is not greater than the previous node's value at any point, the tree is not a BST. If all the visited values are in strictly increasing order, the binary tree is a valid BST.
C++
#include<iostream>#include<climits>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// 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);}intmain(){// 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;}
C
#include<stdio.h>#include<stdlib.h>#include<limits.h>// Definition for a binary tree nodestructNode{intdata;structNode*left;structNode*right;};// 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);}structNode*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;}
Java
// Node structureclassNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{// 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);}publicstaticvoidmain(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");}}}
Python
# Node structureclassNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# 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)if__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")
C#
usingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// 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);}staticvoidMain(){// 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");}}}
JavaScript
// Node structureclassNode{constructor(value){this.data=value;this.left=null;this.right=null;}}// 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// 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");}
Output
false
Using Morris Traversal - O(n) Time and O(1) Space
The idea is to perform an inorder traversal without using recursion or a stack. Morris Traversal temporarily creates links between nodes so that the tree can be traversed using constant extra space. During the traversal, keep track of the previously visited node. If the value of the current node is not greater than the previous node's value, the tree is not a BST. Otherwise, if all the nodes are visited in strictly increasing order, the binary tree is a valid BST. After visiting a node, all the temporary links are removed, restoring the original tree.
C++
#include<iostream>#include<climits>usingnamespacestd;// Node structureclassNode{public:intdata;Node*left;Node*right;Node(intvalue){data=value;left=right=nullptr;}};// 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;}intmain(){// 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;}
C
#include<stdio.h>#include<stdlib.h>#include<limits.h>// Node StructurestructNode{intdata;structNode*left;structNode*right;};// 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;}structNode*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;}
Java
// Node structureclassNode{intdata;Nodeleft,right;Node(intvalue){data=value;left=right=null;}}classGFG{// 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;}publicstaticvoidmain(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");}}}
Python
# Node structureclassNode:def__init__(self,value):self.data=valueself.left=Noneself.right=None# 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.rightreturnTrueif__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")
C#
usingSystem;// Node structureclassNode{publicintdata;publicNodeleft,right;publicNode(intvalue){data=value;left=right=null;}}classGFG{// 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;}staticvoidMain(){// 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");}}}
JavaScript
// Node structureclassNode{constructor(value){this.data=value;this.left=null;this.right=null;}}// 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// 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");}