0
0
DSA C++programming

Validate if Tree is BST in DSA C++

Choose your learning style9 modes available
Mental Model
A binary search tree (BST) is a tree where every node's left child is smaller and right child is bigger than the node itself. We check this by making sure all nodes follow this rule in the whole tree.
Analogy: Imagine a family tree where every child on the left side is younger than their parent, and every child on the right side is older. To confirm it's a proper family tree, you check each parent and their children follow this age rule.
      5
     / \
    3   7
   / \   \
  2   4   8

(Each left child < parent < right child)
Dry Run Walkthrough
Input: Tree: 5 with left child 3 and right child 7; 3 has children 2 and 4; 7 has right child 8
Goal: Check if this tree follows BST rules everywhere
Step 1: Start at root node 5 with allowed range (-∞, +∞)
Node=5, Range=(-∞, +∞)
Why: We begin checking from the root with no limits
Step 2: Check left child 3 with range (-∞, 5)
Node=3, Range=(-∞, 5)
Why: Left child must be less than 5
Step 3: Check left child of 3: node 2 with range (-∞, 3)
Node=2, Range=(-∞, 3)
Why: Left child of 3 must be less than 3
Step 4: Node 2 has no children, return true
Leaf node 2 validated
Why: Leaf nodes are valid by default
Step 5: Check right child of 3: node 4 with range (3, 5)
Node=4, Range=(3, 5)
Why: Right child of 3 must be greater than 3 and less than 5
Step 6: Node 4 has no children, return true
Leaf node 4 validated
Why: Leaf nodes are valid by default
Step 7: Check right child 7 of root 5 with range (5, +∞)
Node=7, Range=(5, +∞)
Why: Right child must be greater than 5
Step 8: Check right child of 7: node 8 with range (7, +∞)
Node=8, Range=(7, +∞)
Why: Right child of 7 must be greater than 7
Step 9: Node 8 has no children, return true
Leaf node 8 validated
Why: Leaf nodes are valid by default
Step 10: All nodes validated, tree is BST
5 -> 3 -> 2,4 and 7 -> 8 all valid
Why: Every node respects BST rules
Result:
5 -> 3 -> 2,4 and 7 -> 8 all valid
Tree is a BST: true
Annotated Code
DSA C++
#include <iostream>
#include <limits>
using namespace std;

struct Node {
    int val;
    Node* left;
    Node* right;
    Node(int v) : val(v), left(nullptr), right(nullptr) {}
};

bool isBSTUtil(Node* node, long long minVal, long long maxVal) {
    if (node == nullptr) return true; // empty node is valid
    if (node->val <= minVal || node->val >= maxVal) return false; // violates BST range
    // check left subtree with updated max
    if (!isBSTUtil(node->left, minVal, node->val)) return false;
    // check right subtree with updated min
    if (!isBSTUtil(node->right, node->val, maxVal)) return false;
    return true; // current node valid and subtrees valid
}

bool isBST(Node* root) {
    return isBSTUtil(root, LLONG_MIN, LLONG_MAX);
}

int main() {
    // Construct tree:
    //       5
    //      / \
    //     3   7
    //    / \   \
    //   2   4   8
    Node* root = new Node(5);
    root->left = new Node(3);
    root->right = new Node(7);
    root->left->left = new Node(2);
    root->left->right = new Node(4);
    root->right->right = new Node(8);

    cout << boolalpha << isBST(root) << endl;
    return 0;
}
if (node == nullptr) return true; // empty node is valid
base case: empty subtree is valid BST
if (node->val <= minVal || node->val >= maxVal) return false; // violates BST range
check current node value against allowed min and max range
if (!isBSTUtil(node->left, minVal, node->val)) return false;
recursively check left subtree with updated max limit
if (!isBSTUtil(node->right, node->val, maxVal)) return false;
recursively check right subtree with updated min limit
return true; // current node valid and subtrees valid
all checks passed, subtree is BST
OutputSuccess
true
Complexity Analysis
Time: O(n) because we visit each node once to check BST property
Space: O(h) where h is tree height due to recursion stack
vs Alternative: Compared to naive approach checking each node's subtree for min/max values repeatedly (O(n^2)), this method is efficient by passing range limits down the tree
Edge Cases
Empty tree (root is nullptr)
Returns true since empty tree is a valid BST
DSA C++
if (node == nullptr) return true; // empty node is valid
Single node tree
Returns true as single node satisfies BST property
DSA C++
if (node == nullptr) return true; // empty node is valid
Tree with duplicate values
Returns false because duplicates violate strict BST property (<= or >= not allowed)
DSA C++
if (node->val <= minVal || node->val >= maxVal) return false; // violates BST range
When to Use This Pattern
When you need to confirm if a binary tree follows the BST rules, use the range-checking pattern that passes min and max limits down the tree to validate each node.
Common Mistakes
Mistake: Only checking immediate children values without considering entire subtree ranges
Fix: Pass down min and max allowed values to each recursive call to ensure all descendants respect BST property
Mistake: Allowing duplicates by using < or > instead of <= or >= in comparisons
Fix: Use strict inequalities (node->val <= minVal or node->val >= maxVal) to disallow duplicates
Summary
Checks if a binary tree is a valid binary search tree by verifying node values fall within allowed ranges.
Use when you need to confirm the BST property for a given binary tree structure.
The key insight is to track and update the allowed min and max value range for each node during traversal.