Check if a Binary Tree is BST or not (original) (raw)
Given the **root of a binary tree, determine whether it is a **Binary Search Tree (BST).
A Binary Search Tree is a binary tree that satisfies the following conditions:
- All nodes in the left subtree have values smaller than the root.
- All nodes in the right subtree have values greater than the root.
- Both left and right subtrees are themselves BSTs.
- All node values are distinct.
**Examples:
**Input:
**Output: false
**Explanation: In the right subtree of 10, all the values must be greater than 10, but 9 < 10.**Input:
**Output: true
**Explanation: Every node follows the property of BST.
Table of Content
- Using Specified range of Min and Max Values
- Using Inorder Traversal
- Using Morris Traversal - O(n) Time and O(1) Space
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 #include using namespace std;
// Node structure class Node { public: int data; Node* left; Node* right;
Node(int value) {
data = value;
left = right = nullptr;
}}; //Driver Code Ends
// Helper function to check if a tree is BST within a given range bool isBSTUtil(Node* node, int min, int max) { if (node == nullptr) return true;
// If the current node's data
// is not in the valid range, return false
if (node->data < min || node->data > max)
return false;
// Recursively check the left and
// right subtrees with updated ranges
return isBSTUtil(node->left, min, node->data - 1) &&
isBSTUtil(node->right, node->data + 1, max);}
// Function to check if the entire binary tree is a BST bool isBST(Node* root) { return isBSTUtil(root, INT_MIN, INT_MAX); }
//Driver Code Starts int main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node* root = new Node(10);
root->left = new Node(5);
root->right = new Node(20);
root->right->left = new Node(9);
root->right->right = new Node(25);
if (isBST(root))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;}
//Driver Code Ends
C
//Driver Code Starts #include <stdio.h> #include <limits.h> #include <stdbool.h>
/// Node structure struct Node { int data; struct Node* left; struct Node* right; }; //Driver Code Ends
// Helper function to check if a tree is BST within a given range bool isBSTUtil(struct Node* node, int min, int max) { if (node == NULL) return true;
// If the current node's data
// is not in the valid range, return false
if (node->data < min || node->data > max) return false;
// Recursively check the left and
// right subtrees with updated ranges
return isBSTUtil(node->left, min, node->data - 1) &&
isBSTUtil(node->right, node->data + 1, max);}
// Function to check if the entire binary tree is a BST bool isBST(struct Node* root) { return isBSTUtil(root, INT_MIN, INT_MAX); }
//Driver Code Starts struct Node* createNode(int value) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = value; newNode->left = newNode->right = NULL; return newNode; }
int main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
struct Node* 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");
else
printf("false");
return 0;}
//Driver Code Ends
Java
//Driver Code Starts // Node structure class Node { int data; Node left, right;
Node(int value) {
data = value;
left = right = null;
}}
class GFG { //Driver Code Ends
// Helper function to check if a tree is BST within a given range
static boolean isBSTUtil(Node node, int min, int max) {
if (node == null) return true;
// If the current node's data
// is not in the valid range,
// return false
if (node.data < min || node.data > max) return false;
// Recursively check the left and
// right subtrees with updated ranges
return isBSTUtil(node.left, min, node.data - 1) &&
isBSTUtil(node.right, node.data + 1, max);
}
// Function to check if the entire binary tree is a BST
static boolean isBST(Node root) {
return isBSTUtil(root, Integer.MIN_VALUE, Integer.MAX_VALUE);
}//Driver Code Starts public static void main(String[] args) {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(20);
root.right.left = new Node(9);
root.right.right = new Node(25);
if (isBST(root)) {
System.out.println("true");
}
else {
System.out.println("false");
}
}}
//Driver Code Ends
Python
#Driver Code Starts
Node structure
class Node: def init(self, value): self.data = value self.left = None self.right = None #Driver Code Ends
Helper function to check if a tree is
BST within a given range
def isBstUtil(node, min_val, max_val): if node is None: return True
# If the current node's data
# is not in the valid range, return false
if node.data < min_val or node.data > max_val:
return False
# Recursively check the left and
# right subtrees with updated ranges
return (isBstUtil(node.left, min_val, node.data - 1) and
isBstUtil(node.right, node.data + 1, max_val))
Function to check if the entire binary tree is a BST
def isBST(root): return isBstUtil(root, float('-inf'), float('inf'))
#Driver Code Starts if name == "main":
# Create a sample binary tree
# 10
# / \
# 5 20
# / \
# 9 25
root = Node(10)
root.left = Node(5)
root.right = Node(20)
root.right.left = Node(9)
root.right.right = Node(25)
if isBST(root):
print("true")
else:
print("false")#Driver Code Ends
C#
//Driver Code Starts using System;
// Node structure class Node { public int data; public Node left, right;
public Node(int value) {
data = value;
left = right = null;
}}
class GFG { //Driver Code Ends
// Helper function to check if a tree is BST within a given range
static bool isBSTUtil(Node node, int min, int max) {
if (node == null) return true;
// If the current node's data
// is not in the valid range, return false
if (node.data < min || node.data > max) return false;
// Recursively check the left and
// right subtrees with updated ranges
return isBSTUtil(node.left, min, node.data - 1) &&
isBSTUtil(node.right, node.data + 1, max);
}
// Function to check if the entire binary tree is a BST
static bool isBST(Node root) {
return isBSTUtil(root, int.MinValue, int.MaxValue);
}//Driver Code Starts static void Main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(20);
root.right.left = new Node(9);
root.right.right = new Node(25);
if (isBST(root)) {
Console.WriteLine("true");
}
else {
Console.WriteLine("false");
}
}}
//Driver Code Ends
JavaScript
//Driver Code Starts // Node structure class Node { 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 range function isBSTUtil(node, min, max) { if (node === null) return true;
// If the current node's data
// is not in the valid range, return false
if (node.data < min || node.data > max) return false;
// Recursively check the left and
// right subtrees with updated ranges
return isBSTUtil(node.left, min, node.data - 1) &&
isBSTUtil(node.right, node.data + 1, max);}
// Function to check if the entire binary tree is a BST function isBST(root) { return isBSTUtil(root, -Infinity, Infinity); }
//Driver Code Starts // Driver Code
// Create a sample binary tree
// 10
// /
// 5 20
// /
// 9 25
const root = new Node(10); root.left = new Node(5); root.right = new Node(20); root.right.left = new Node(9); root.right.right = new Node(25);
if (isBST(root)) { console.log("true"); } else { console.log("false"); }
//Driver Code Ends
`
**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).
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 #include using namespace std;
// Node structure class Node { public: int data; Node* left; Node* right;
Node(int value) {
data = value;
left = right = nullptr;
}}; //Driver Code Ends
// Recursive Function for inorder traversal bool inorder(Node* root, int &prev) { if (!root) return true;
// Recursively check the left subtree
if (!inorder(root->left, prev))
return false;
// Check the current node value
// against the previous value
if (prev >= root->data)
return false;
prev = root->data;
// Recursively check the right subtree
return inorder(root->right, prev);}
// Function to check if the entire binary tree is a BST bool isBST(Node* root) { int prev = INT_MIN; return inorder(root, prev); }
//Driver Code Starts int main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node* root = new Node(10);
root->left = new Node(5);
root->right = new Node(20);
root->right->left = new Node(9);
root->right->right = new Node(25);
if (isBST(root))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;}
//Driver Code Ends
C
//Driver Code Starts #include <stdio.h> #include <stdlib.h> #include <limits.h>
// Definition for a binary tree node struct Node { int data; struct Node* left; struct Node* right; };
//Driver Code Ends
// Recursive Function for inorder traversal int isValidBST(struct Node* root, int* prev) { if (root == NULL) return 1;
// Recursively check the left subtree
if (!isValidBST(root->left, prev)) return 0;
// Check the current node value
// against the previous value
if (*prev >= root->data) return 0;
*prev = root->data;
// Recursively check the right subtree
return isValidBST(root->right, prev);}
// Function to check if the entire binary tree is a BST int isBST(struct Node* root) { int prev = INT_MIN; return isValidBST(root, &prev); }
//Driver Code Starts struct Node* createNode(int value) { struct Node* node = (struct Node*)malloc(sizeof(struct Node)); node->data = value; node->left = NULL; node->right = NULL; return node; }
int main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
struct Node* 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");
else
printf("false");
return 0;}
//Driver Code Ends
Java
//Driver Code Starts // Node structure class Node { int data; Node left, right;
Node(int value) {
data = value;
left = right = null;
}}
class GFG { //Driver Code Ends
// Recursive Function for inorder traversal
static boolean inorder(Node root, int[] prev) {
if (root == null)
return true;
// Recursively check the left subtree
if (!inorder(root.left, prev))
return false;
// Check the current node value
// against the previous value
if (prev[0] >= root.data)
return false;
prev[0] = root.data;
// Recursively check the right subtree
return inorder(root.right, prev);
}
// Function to check if the entire binary tree is a BST
static boolean isBST(Node root) {
int[] prev = {Integer.MIN_VALUE};
return inorder(root, prev);
}//Driver Code Starts public static void main(String[] args) {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(20);
root.right.left = new Node(9);
root.right.right = new Node(25);
if (isBST(root)) {
System.out.println("true");
}
else {
System.out.println("false");
}
}}
//Driver Code Ends
Python
#Driver Code Starts
Node structure
class Node: def init(self, value): self.data = value self.left = None self.right = None #Driver Code Ends
Recursive Function for inorder traversal
def inorder(root, prev): if root is None: return True
# Recursively check the left subtree
if not inorder(root.left, prev):
return False
# Check the current node value
# against the previous value
if prev[0] >= root.data:
return False
prev[0] = root.data
# Recursively check the right subtree
return inorder(root.right, prev)Function to check if the entire binary tree is a BST
def isBST(root): prev = [float('-inf')] return inorder(root, prev)
#Driver Code Starts if name == "main":
# Create a sample binary tree
# 10
# / \
# 5 20
# / \
# 9 25
root = Node(10)
root.left = Node(5)
root.right = Node(20)
root.right.left = Node(9)
root.right.right = Node(25)
if isBST(root):
print("true")
else:
print("false")#Driver Code Ends
C#
//Driver Code Starts using System;
// Node structure class Node { public int data; public Node left, right;
public Node(int value) {
data = value;
left = right = null;
}}
class GFG { //Driver Code Ends
// Recursive Function for inorder traversal
static bool inorder(Node root, ref int prev) {
if (root == null)
return true;
// Recursively check the left subtree
if (!inorder(root.left, ref prev))
return false;
// Check the current node value
// against the previous value
if (prev >= root.data)
return false;
prev = root.data;
// Recursively check the right subtree
return inorder(root.right, ref prev);
}
// Function to check if the entire binary tree is a BST
static bool isBST(Node root) {
int prev = int.MinValue;
return inorder(root, ref prev);
}//Driver Code Starts static void Main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(20);
root.right.left = new Node(9);
root.right.right = new Node(25);
if (isBST(root)) {
Console.WriteLine("true");
}
else {
Console.WriteLine("false");
}
}}
//Driver Code Ends
JavaScript
//Driver Code Starts // Node structure
class Node { constructor(value) { this.data = value; this.left = null; this.right = null; } } //Driver Code Ends
// Recursive Function for inorder traversal function inorder(root, prev) { if (root === null) return true;
// Recursively check the left subtree
if (!inorder(root.left, prev))
return false;
// Check the current node value
// against the previous value
if (prev[0] >= root.data)
return false;
prev[0] = root.data;
// Recursively check the right subtree
return inorder(root.right, prev);}
// Function to check if the entire binary tree is a BST function isBST(root) { let prev = [-Infinity]; return inorder(root, prev); }
//Driver Code Starts // Driver Code
// Create a sample binary tree
// 10
// /
// 5 20
// /
// 9 25
const root = new Node(10); root.left = new Node(5); root.right = new Node(20); root.right.left = new Node(9); root.right.right = new Node(25);
if (isBST(root)) { console.log("true"); } else { console.log("false"); }
//Driver Code Ends
`
**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).
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 #include using namespace std;
// Node structure class Node { public: int data; Node* left; Node* right;
Node(int value) {
data = value;
left = right = nullptr;
}}; //Driver Code Ends
// Function to check if the binary tree // is a BST using Morris Traversal bool isBST(Node* root) { Node* curr = root; Node* pre = nullptr; int prevValue = INT_MIN;
while (curr != nullptr) {
if (curr->left == nullptr) {
if (curr->data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr->data;
curr = curr->right;
} else {
// Find the inorder predecessor of curr
pre = curr->left;
while (pre->right != nullptr && pre->right != curr) {
pre = pre->right;
}
if (pre->right == nullptr) {
// Create a temporary
// thread to the curr node
pre->right = curr;
curr = curr->left;
} else {
pre->right = nullptr;
if (curr->data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr->data;
curr = curr->right;
}
}
}
return true; }
//Driver Code Starts int main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node* root = new Node(10);
root->left = new Node(5);
root->right = new Node(20);
root->right->left = new Node(9);
root->right->right = new Node(25);
if (isBST(root))
cout << "true" << endl;
else
cout << "false" << endl;
return 0;}
//Driver Code Ends
C
//Driver Code Starts #include <stdio.h> #include <stdlib.h> #include <limits.h>
// Node Structure struct Node { int data; struct Node* left; struct Node* right; //Driver Code Ends
};
// Function to check if the binary tree // is a BST using Morris Traversal int isBST(struct Node* root) { struct Node* curr = root; struct Node* pre; int prevValue = INT_MIN;
while (curr != NULL) {
if (curr->left == NULL) {
if (curr->data <= prevValue) {
// Not in ascending order
return 0;
}
prevValue = curr->data;
curr = curr->right;
} else {
// Find the inorder predecessor of curr
pre = curr->left;
while (pre->right != NULL && pre->right != curr) {
pre = pre->right;
}
if (pre->right == NULL) {
// Create a temporary
// thread to the curr node
pre->right = curr;
curr = curr->left;
} else {
pre->right = NULL;
if (curr->data <= prevValue) {
// Not in ascending order
return 0;
}
prevValue = curr->data;
curr = curr->right;
}
}
}
return 1; }
//Driver Code Starts
struct Node* createNode(int value) { struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); newNode->data = value; newNode->left = newNode->right = NULL; return newNode; }
int main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
struct Node* 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");
else
printf("false");
return 0;}
//Driver Code Ends
Java
//Driver Code Starts // Node structure class Node { int data; Node left, right;
Node(int value) {
data = value;
left = right = null;
}}
class GFG { //Driver Code Ends
// Function to check if the binary tree
// is a BST using Morris Traversal
static boolean isBST(Node root) {
Node curr = root;
Node pre;
int prevValue = Integer.MIN_VALUE;
while (curr != null) {
if (curr.left == null) {
if (curr.data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr.data;
curr = curr.right;
} else {
// Find the inorder predecessor of curr
pre = curr.left;
while (pre.right != null && pre.right != curr) {
pre = pre.right;
}
if (pre.right == null) {
// Create a temporary thread
// to the curr node
pre.right = curr;
curr = curr.left;
} else {
pre.right = null;
if (curr.data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr.data;
curr = curr.right;
}
}
}
return true;
}//Driver Code Starts public static void main(String[] args) {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(20);
root.right.left = new Node(9);
root.right.right = new Node(25);
if (isBST(root)) {
System.out.println("true");
}
else {
System.out.println("false");
}
}}
//Driver Code Ends
Python
#Driver Code Starts
Node structure
class Node: def init(self, value): self.data = value self.left = None self.right = None #Driver Code Ends
Function to check if the binary tree
is a BST using Morris Traversal
def isBST(root): curr = root prevValue = float('-inf')
while curr:
if curr.left is None:
if curr.data <= prevValue:
# Not in ascending order
return False
prevValue = curr.data
curr = curr.right
else:
# Find the inorder predecessor of curr
pre = curr.left
while pre.right and pre.right != curr:
pre = pre.right
if pre.right is None:
# Create a temporary
# thread to the curr node
pre.right = curr
curr = curr.left
else:
pre.right = None
if curr.data <= prevValue:
# Not in ascending order
return False
prevValue = curr.data
curr = curr.right
return True#Driver Code Starts if name == "main":
# Create a sample binary tree
# 10
# / \
# 5 20
# / \
# 9 25
root = Node(10)
root.left = Node(5)
root.right = Node(20)
root.right.left = Node(9)
root.right.right = Node(25)
if isBST(root):
print("true")
else:
print("false")#Driver Code Ends
C#
//Driver Code Starts using System;
// Node structure class Node { public int data; public Node left, right;
public Node(int value) {
data = value;
left = right = null;
}}
class GFG { //Driver Code Ends
// Function to check if the binary tree
// is a BST using Morris Traversal
static bool isBST(Node root) {
Node curr = root;
Node pre;
int prevValue = int.MinValue;
while (curr != null) {
if (curr.left == null) {
if (curr.data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr.data;
curr = curr.right;
} else {
// Find the inorder predecessor of curr
pre = curr.left;
while (pre.right != null && pre.right != curr) {
pre = pre.right;
}
if (pre.right == null) {
// Create a temporary
// thread to the curr node
pre.right = curr;
curr = curr.left;
} else {
pre.right = null;
if (curr.data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr.data;
curr = curr.right;
}
}
}
return true;
}//Driver Code Starts static void Main() {
// Create a sample binary tree
// 10
// / \
// 5 20
// / \
// 9 25
Node root = new Node(10);
root.left = new Node(5);
root.right = new Node(20);
root.right.left = new Node(9);
root.right.right = new Node(25);
if (isBST(root)) {
Console.WriteLine("true");
}
else {
Console.WriteLine("false");
}
}}
//Driver Code Ends
JavaScript
//Driver Code Starts // Node structure class Node { 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 Traversal function isBST(root) { let curr = root; let prevValue = -Infinity;
while (curr !== null) {
if (curr.left === null) {
if (curr.data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr.data;
curr = curr.right;
} else {
// Find the inorder predecessor of curr
let pre = curr.left;
while (pre.right !== null && pre.right !== curr) {
pre = pre.right;
}
if (pre.right === null) {
// Create a temporary
// thread to the curr node
pre.right = curr;
curr = curr.left;
} else {
pre.right = null;
if (curr.data <= prevValue) {
// Not in ascending order
return false;
}
prevValue = curr.data;
curr = curr.right;
}
}
}
return true;}
//Driver Code Starts // Driver Code
// Create a sample binary tree
// 10
// /
// 5 20
// /
// 9 25
const root = new Node(10); root.left = new Node(5); root.right = new Node(20); root.right.left = new Node(9); root.right.right = new Node(25);
if (isBST(root)) { console.log("true"); } else { console.log("false"); } //Driver Code Ends
`

