// Error a propósito: un check_invariants que solo mira a los hijos directos.
// Aprueba un árbol roto, en el que una clave que está no se puede encontrar.
#include <iostream>

struct Node {
    int key;
    Node* left;
    Node* right;
};

bool looks_fine(const Node* node) {
    if (node == nullptr) {
        return true;
    }
    if (node->left != nullptr && !(node->left->key < node->key)) {
        return false;
    }
    if (node->right != nullptr && !(node->key < node->right->key)) {
        return false;
    }
    return looks_fine(node->left) && looks_fine(node->right);
}

bool contains(const Node* node, int key) {
    while (node != nullptr) {
        if (key == node->key) {
            return true;
        }
        node = key < node->key ? node->left : node->right;
    }
    return false;
}

int main() {
    // El 7 está a la derecha del 3, bien, pero dentro del subárbol izquierdo del 5.
    Node seven{7, nullptr, nullptr};
    Node three{3, nullptr, &seven};
    Node root{5, &three, nullptr};
    std::cout << "revision local: " << (looks_fine(&root) ? "todo bien" : "roto") << "\n";
    std::cout << "contains(7): " << (contains(&root, 7) ? "si" : "no") << "\n";
    return 0;
}
