PrepStack · Markdown HTML

BST ordering / inorder traversal

Tree, BST, and trie · HTML

Formal shape

For a strict BST, every left-subtree value < node.val < every right-subtree value. Validate by inherited (low,high) bounds or strictly increasing inorder prev. Search discards an entire subtree after each comparison. Duplicate policy must be explicit.

Recognition signals

False friends

SignalWhy it is different
An ordinary binary treeWithout global ordering, value-based pruning and sorted inorder are invalid.
Checking only direct childrenA distant descendant can violate an ancestor bound while satisfying its local parent comparison.
Duplicates with unspecified placementStrict, equal-left, and equal-right policies change bounds and inorder comparisons.

Core invariant

At node entry, (low,high) is the intersection of all ancestor constraints; a legal value lies inside it. In inorder form, every visited value is greater than the previous one.

State, transition, and processing order

ItemDefinition
StateCurrent node plus ancestor bounds, or an iterative inorder stack with prev and optional visit rank.
TransitionValidation sends (low,node.val) left and (node.val,high) right; rank queries increment when an inorder node is popped.
Frontier / orderSearch follows one root-to-leaf path; inorder keeps ancestors whose node/right subtree remain unvisited.

Python skeleton

def is_valid_bst(root):
    stack, node = [], root
    prev = None
    while stack or node:
        while node:
            stack.append(node)
            node = node.left
        node = stack.pop()
        if prev is not None and node.val <= prev:
            return False
        prev = node.val
        node = node.right
    return True

Correctness sketch

  1. The BST definition makes inorder visit all smaller left values, then the node, then all larger right values, so a valid tree is strictly increasing.
  2. Conversely, a strictly increasing inorder segment puts every left-subtree value before and below its node and every right value after and above it, recursively satisfying global order.
  3. The template checks every adjacent inorder pair, exactly testing this equivalent condition.

Complexity

TimeSpaceParameters
O(n) validation/full traversal; search is O(h), O(log n) only when balanced and O(n) worst-caseO(h) stackn is node count and h tree height.

Edge cases

Error patterns

PatternWhy it fails / fix
Comparing only immediate childrenIt misses a right-descendant value below a distant ancestor; use inherited bounds or global inorder.
Using a finite integer as infinityA node may equal that sentinel; use None or mathematical infinity.
Testing prev by truthinessZero is a valid previous value; test prev is not None.
Assuming every BST is balancedSearch is O(h), and a skewed tree has h=n.

Selection and exclusion rules

RelationTemplateBoundary
alternativeFenwick treeOffline compressed-domain dynamic ranks fit a Fenwick tree better than maintaining a BST.

Original micro-example

PartDetail
ResultInherited bounds or inorder [3,9,8] both reject the tree.
SetupRoot 8 has left child 3, and node 3 has right child 9.
Trace9>3 passes its local parent check but lies in root 8's left subtree and violates upper bound 8.

Recall prompts

My notes