Check if a Binary Tree is BST or not

Last Updated : 30 Jul, 2026

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:

420046837

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.

420046836

Output: true
Explanation: Every node satisfies the BST property. Hence, the given binary tree is a valid BST.

Try It Yourself
redirect icon

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>
using namespace std;

// Node structure
class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int value) {
        data = value;
        left = right = nullptr;
    }
};

// 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);
}

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;
}
C
#include <stdio.h>
#include <limits.h>
#include <stdbool.h>

/// Node structure
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};

// 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);
}

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;
}
Java
// Node structure
class Node {
    int data;
    Node left, right;

    Node(int value) {
        data = value;
        left = right = null;
    }
}

class GFG {
  
    // 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);
    }

    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");
        }
    }
}
Python
# Node structure
class Node:
    def __init__(self, value):
        self.data = value
        self.left = None
        self.right = None

# 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'))

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")
C#
using System;

// Node structure
class Node {
    public int data;
    public Node left, right;

    public Node(int value) {
        data = value;
        left = right = null;
    }
}

class GFG {
  
    // 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);
    }

    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");
        }
    }
}
JavaScript
// Node structure
class Node {
    constructor(value) {
        this.data = value;
        this.left = this.right = null;
    }
}

// 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

// 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");
}

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>
using namespace std;

// Node structure
class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int value) {
        data = value;
        left = right = nullptr;
    }
};

// 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);
}

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;
}
C
#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;
};

// 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);
}

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;
}
Java
// Node structure
class Node {
    int data;
    Node left, right;

    Node(int value) {
        data = value;
        left = right = null;
    }
}

class GFG {
  
    // 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);
    }

    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");
        }
    }
}
Python
# Node structure
class Node:
    def __init__(self, value):
        self.data = value
        self.left = None
        self.right = None

# 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)

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")
C#
using System;

// Node structure
class Node {
    public int data;
    public Node left, right;

    public Node(int value) {
        data = value;
        left = right = null;
    }
}

class GFG {
  
    // 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);
    }

    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");
        }
    }
}
JavaScript
// Node structure

class Node {
    constructor(value) {
        this.data = value;
        this.left = null;
        this.right = null;
    }
}

// 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

// 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");
}

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>
using namespace std;

// Node structure
class Node {
public:
    int data;
    Node* left;
    Node* right;

    Node(int value) {
        data = value;
        left = right = nullptr;
    }
};

// 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; 
}

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;
}
C
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>

// Node Structure
struct Node {
    int data;
    struct Node* left;
    struct Node* right;
};

// 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; 
}

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;
}
Java
// Node structure
class Node {
	int data;
	Node left, right;

	Node(int value) {
        data = value;
        left = right = null;
	}
}

class GFG {

    // 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;
    }

    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");
        }
    }
}
Python
# Node structure
class Node:
    def __init__(self, value):
        self.data = value
        self.left = None
        self.right = None

#  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

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")
C#
using System;

// Node structure
class Node {
	public int data;
	public Node left, right;

	public Node(int value) {
		data = value;
		left = right = null;
	}
}

class GFG {

    // 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;
    }

    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");
        }
    }
}
JavaScript
// Node structure
class Node {
    constructor(value) {
        this.data = value;
        this.left = null;
        this.right = null;
    }
}

// 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

// 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");
}

Output
false
Comment