Check if Binary Search Tree I wrote this entirely from scratch without any Googling/reading as part of an ongoing effort to improve my problem-solving skills.

Also, please note that the focus for my project was the problem solving steps rather than the code itself, which is why I have the comments. It is also why I manually set up the BST (this helped me visualize the problem in order to solve it). However, I am indeed asking for a code review.

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdbool.h&gt;
typedef struct Node {
      int data;
      struct Node* left;
      struct Node* right;
      struct Node* parent;
   } node;
bool checkBST(node *root){

    //Step 1, check if the node is not null *******
    //Step 2, check if left child exists **********
    //Step 3, if left child exists, compare its data to the root/current node's data and make sure that it is SMALLER **********
    //step 4, if the data is smaller, proceed, else return false ***********
    //step 5, if the root's right child exists, compare its data to the root/current node's data and make sure it is BIGGER *********
    //step 6, if the data is bigger, proceed, else return false *******

    //step 7, recurse *****
    //step 8, return true *****

    if(root == NULL){
        printf("root is null!\n");
        return false;
    }


    if(root-&gt;left != NULL){
        printf("root data: %d\nleft data: %d\n",root-&gt;data,root-&gt;left-&gt;data);
        if(root-&gt;data &lt; root-&gt;left-&gt;data){
            printf("Not a BST: left is bigger\n");
            return false;
        }
        checkBST(root-&gt;left);
    }

    if(root-&gt;right != NULL){
        printf("root data: %d\nright data: %d\n",root-&gt;data,root-&gt;right-&gt;data);
        if(root-&gt;data &gt; root-&gt;right-&gt;data){
            printf("Not a BST: right is smaller\n");
            return false;
        }
        checkBST(root-&gt;right);
    }

    return true;
}

int main(){
    node *n1, *n2, *root, *n4, *n5, *n6;

    n1 = malloc(sizeof(node));
    n2 = malloc(sizeof(node));
    root = malloc(sizeof(node));
    n4 = malloc(sizeof(node));
    n5 = malloc(sizeof(node));
    n6 = malloc(sizeof(node));

    //Set up data values
    n1-&gt;data = 10;
    n2-&gt;data = 20;
    root-&gt;data = 30;
    n4-&gt;data = 15; //modified this node to test for negative outcome
    n5-&gt;data = 50;
    n6-&gt;data = 60;

    //Set up children/parents
    root-&gt;parent = NULL;
    root-&gt;left = n2;
    root-&gt;right = n4;
    n1-&gt;left = NULL;
    n1-&gt;right = NULL;
    n2-&gt;parent = root;
    n2-&gt;left = n1;
    n2-&gt;right = NULL;
    n4-&gt;parent = root;
    n4-&gt;left = NULL;
    n4-&gt;right = n5;
    n5-&gt;parent = n4;
    n5-&gt;left = NULL;
    n5-&gt;right = n6;
    n6-&gt;parent = n5;
    n6-&gt;left = NULL;
    n6-&gt;right = NULL;


if(checkBST(root) == true){
    printf("This is a BST!");
}

    return(EXIT_SUCCESS);
}
You forgot to check the result of your recursing calls. Your steps are fine, if you meant the following in step 7


  Step 7: recurse and check result


However, even then, it's not the correct property of a binary search tree. Have a look at the following tree:

    5
   / \
  3   7
 / \
1   6


Does this hold for your steps? Yes. Does this hold for your algorithm, if you check the result of checkBST?

bool checkBST(node *root){
    if(root == NULL){
        return false;
    }    

    if(root-&gt;left != NULL){
        if(root-&gt;data &lt; root-&gt;left-&gt;data || !checkBST(root-&gt;left)){
            return false;
        }
    }

    if(root-&gt;right != NULL){
        if(root-&gt;data &gt; root-&gt;right-&gt;data || !checkBST(root-&gt;right)){
            return false;
        }
    }

    return true;
}


Yes. But is it a binary search tree? No. You would never find 6. All nodes left of the root must be smaller, and all nodes right of the root must be greater.

Remember, a binary tree has the following property: if you want to find a value, you look at the current value. If the value you're looking for is smaller, you continue in the left tree. If the value is greater, you continue in the right tree. But you always look at one of those subtrees. Never both. In a balanced binary tree, you would only have to look at \$\log_2(N)\$ nodes to find your value.

I would link you to the Wikipedia section on Verification, but it already holds the solution. But here is a hint: carry along what numbers are allowed in your subtree.

So, to go back to your steps, you should do something like this:


check if the node is not null 
check if left child exists


check that all elements in the left subtree are smaller than our current value

check if right child exists


check that all elements in the right subtree are greater than our current value



The steps 0 and 1.5 are missing. They handle the current value and the range of valid values. Coming up with them will be the crucial part.

By the way, you usually don't use parent in a binary tree. But that depends on your use-case. Also, you have memory leaks. For small examples, there is no harm not using malloc:

struct node n10, n20, n30, n15, n50, n60;

n10.data = 10;
n10.left = NULL
n10.right = NULL
n10.parent = &amp;n20;

n20.data   = 20;
n20.parent = &amp;root;
n20.left   = &amp;n10;
n20.right  = NULL;

// ....