Validating Structural Properties of Binary Search Trees

A Binary Search Tree (BST) is defined as either an empty tree or a tree satisfying these conditions: for any node, all values in its left subtree are less than its own value, and all values in its right subtree are greater. Both subtrees must also be BSTs.

Given a sequence of unique integers, insert them sequentially into an initial empty BST. Subsequently, evaluate a series of statements about the tree's strutcure for correctness.

Input Format: The first line contains a positive integer N (≤100). The next line provides N distinct integers separated by spaces for sequential insertion into the BST. Following that is a positive integer M (≤100). Then M lines follow, each containing a statement to be judged, falling into one of six types:

  • A is the root
  • A and B are siblings
  • A is the parent of B
  • A is the left child of B
  • A is the right child of B
  • A and B are on the same level All integers are within the standard integer range.

Output Format: For each statement, output Yes if correct, otherwise No, each on a new line.

Sample Input:

5
2 4 1 3 0
8
2 is the root
1 and 4 are siblings
3 and 0 are on the same level
2 is the parent of 4
3 is the left child of 4
1 is the right child of 2
4 and 0 are on the same level
100 is the right child of 3

Sample Output:

Yes
Yes
Yes
Yes
Yes
No
No
No

Since N ≤ 100, a chain-like BST could theoretically require a very large array index range. Using map as a dynamic array is a practical solution. Each unique value is stored with its corresponding index, and a reverse mapping from value to index is maintained. Let indices for values A and B be idxA and idxB. The structural checks correspond to:

  • Root: idxA == 1
  • Siblings: (idxA | 1) == idxB || (idxB | 1) == idxA
  • Parent: (idxB / 2) == idxA
  • Left Child: (idxB * 2) == idxA
  • Right Child: (idxB * 2 + 1) == idxA
  • Same Level: Determine the power-of-two range containing each index and compare.
#include <iostream>
#include <string>
#include <map>
using namespace std;

map<int, int> indexMap; // Maps tree index -> node value
map<int, int> valueToIndex; // Maps node value -> tree index

void insertNode(int currentIdx, int value) {
    if (!indexMap.count(currentIdx)) {
        indexMap[currentIdx] = value;
        valueToIndex[value] = currentIdx;
    } else if (indexMap[currentIdx] > value) {
        insertNode(currentIdx * 2, value);
    } else {
        insertNode(currentIdx * 2 + 1, value);
    }
}

int getIndex(int value) {
    if (valueToIndex.count(value)) {
        return valueToIndex[value];
    }
    return -1; // Value not found in tree
}

bool checkRoot(int idx) {
    return idx == 1;
}

bool checkSiblings(int idx1, int idx2) {
    if (idx1 <= 0 || idx2 <= 0) return false;
    return ((idx1 | 1) == idx2) || ((idx2 | 1) == idx1);
}

bool checkParent(int parentIdx, int childIdx) {
    if (parentIdx <= 0 || childIdx <= 0) return false;
    return (childIdx / 2) == parentIdx;
}

bool checkLeftChild(int childIdx, int parentIdx) {
    if (childIdx <= 0 || parentIdx <= 0) return false;
    return (parentIdx * 2) == childIdx;
}

bool checkRightChild(int childIdx, int parentIdx) {
    if (childIdx <= 0 || parentIdx <= 0) return false;
    return (parentIdx * 2 + 1) == childIdx;
}

bool checkSameLevel(int idx1, int idx2) {
    if (idx1 <= 0 || idx2 <= 0) return false;
    int level1 = 0, level2 = 0;
    int temp1 = idx1, temp2 = idx2;
    while (temp1 > 1) { temp1 >>= 1; level1++; }
    while (temp2 > 1) { temp2 >>= 1; level2++; }
    return level1 == level2;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int nodeCount;
    cin >> nodeCount;
    for (int i = 0; i < nodeCount; ++i) {
        int val;
        cin >> val;
        insertNode(1, val);
    }

    int queryCount;
    cin >> queryCount;
    cin.ignore(); // Handle newline after integer input
    for (int i = 0; i < queryCount; ++i) {
        string line;
        getline(cin, line);
        // Parse the statement
        size_t pos = line.find(' ');
        string firstToken = line.substr(0, pos);
        int valA = stoi(firstToken);
        int idxA = getIndex(valA);
        bool result = false;

        if (line.find("and") != string::npos) {
            // Format: "A and B ..."
            size_t andPos = line.find("and", pos+1);
            string secondNum = line.substr(andPos + 4);
            secondNum = secondNum.substr(0, secondNum.find(' '));
            int valB = stoi(secondNum);
            int idxB = getIndex(valB);

            if (line.find("siblings") != string::npos) {
                result = checkSiblings(idxA, idxB);
            } else { // "on the same level"
                result = checkSameLevel(idxA, idxB);
            }
        } else if (line.find("root") != string::npos) {
            result = checkRoot(idxA);
        } else if (line.find("parent") != string::npos) {
            size_t ofPos = line.find("of", pos+1);
            string secondNum = line.substr(ofPos + 3);
            int valB = stoi(secondNum);
            int idxB = getIndex(valB);
            result = checkParent(idxA, idxB);
        } else if (line.find("left child") != string::npos) {
            size_t ofPos = line.find("of", pos+1);
            string secondNum = line.substr(ofPos + 3);
            int valB = stoi(secondNum);
            int idxB = getIndex(valB);
            result = checkLeftChild(idxA, idxB);
        } else if (line.find("right child") != string::npos) {
            size_t ofPos = line.find("of", pos+1);
            string secondNum = line.substr(ofPos + 3);
            int valB = stoi(secondNum);
            int idxB = getIndex(valB);
            result = checkRightChild(idxA, idxB);
        }
        cout << (result ? "Yes" : "No") << '\n';
    }
    return 0;
}

Tags: Binary Search Tree Data Structures algorithm C++ tree validation

Posted on Wed, 13 May 2026 14:51:39 +0000 by vaanil