Understanding the Execution Order of Logic in Binary Tree Recursion

The placement of code within a recursive function significantly impacts how the program interatcs with the state of a binary tree. This is particularly evident when using external or persistent variables to track the relationship between different nodes during traversal.

Impact of Early Assignment

When calculating the minimum absolute difference between nodes in a Binary Search Tree (BST), the goal is to compare the current node with the one immediately preceding it in an in-order sequence. Placing the update logic at the very beginning of the recursive function—before any sub-tree exploration—renders the tracking variable redundant.

class Solution {
private:
    int minGap = INT_MAX;
    TreeNode* previousNode = nullptr;

    void compute(TreeNode* currentNode) {
        if (!currentNode) return;

        // Incorrect placement: updating state before exploring children
        previousNode = currentNode;

        compute(currentNode->left);
        if (previousNode) {
            minGap = std::min(minGap, currentNode->val - previousNode->val);
        }
        compute(currentNode->right);
    }

public:
    int getMinimumDifference(TreeNode* root) {
        compute(root);
        return minGap;
    }
};

In this scenario, code executed before the recursive calls runs as soon as the function enters a new node. Assigning previousNode = currentNode here makes previousNode identical to the current parameter. Since the recursive call already has access to the current node via its arguments, this assignment provides no historical context from previously visited nodes.

Correct Sequencing for In-Order Traversal

To effectively track the predecessor in a BST, the state update must occur between the exploration of the left child and the right child. This ensures that the "previous" pointer always references the node visited just before the current one in sorted order.

class Solution {
private:
    int minDiff = INT_MAX;
    TreeNode* lastVisited = nullptr;

    void findMin(TreeNode* node) {
        if (!node) return;

        // Traverse the left subtree
        findMin(node->left);

        // Process the current node
        if (lastVisited != nullptr) {
            minDiff = std::min(minDiff, node->val - lastVisited->val);
        }
        
        // Update the state for the next node in the sequence
        lastVisited = node;

        // Traverse the right subtree
        findMin(node->right);
    }

public:
    int getMinimumDifference(TreeNode* root) {
        findMin(root);
        return minDiff;
    }
};

By placing the logic after the left recursion, the following behaviors are established:

  1. State Preservation: The lastVisited variable correctly holds the reference to the rightmost node of the current node's left subtree (or its parent, depending on the position), which is the immediate predecessor in in-order traversal.
  2. Sequential Processing: The update lastVisited = node occurs only after the comparison logic is finished for the current node, ensuring that the next node visited (the leftmost node of the right subtree) can correctly calculate its difference relative to the current node.

Tags: binary tree Recursion BST algorithms C++

Posted on Sun, 07 Jun 2026 18:17:22 +0000 by djsl