Lookups in list in C I read about lookups in lists and I think that is what I did. I would like to compare it to a skip list, a binary search or a B+ tree. 

#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;time.h&gt;

typedef struct node {
    int node_id;
    int data;
    struct node *left;
    struct node *right;
} node;


node *newNode(int data, int node_id) {
    node *new_node = (node *) malloc(sizeof(node));
    new_node-&gt;data = data;
    new_node-&gt;node_id = node_id;
    new_node-&gt;right = new_node-&gt;left = NULL;
    return new_node;
}

node *insert_node(node *root, int data, int node_id) {
    if (root == NULL)
        return newNode(data, node_id);
    else {
        node *cur;
        if (node_id &lt; root-&gt;node_id) {
            cur = insert_node(root-&gt;left, data, node_id);
            root-&gt;left = cur;
        } else if (node_id &gt; root-&gt;node_id) {
            cur = insert_node(root-&gt;right, data, node_id);
            root-&gt;right = cur;
        }
    }
    return root;
}


node *find_node_data(node *root, int node_id) {
    if (root == NULL)
        return NULL;
    else if (root-&gt;node_id == node_id)
        return root;
    else if (root-&gt;node_id &gt; node_id)
        return find_node_data(root-&gt;left, node_id);
    else
        return find_node_data(root-&gt;right, node_id);
}

void print(node *np) {
    if (np) {
        print(np-&gt;left);
        printf("(%d, %d)", np-&gt;node_id, np-&gt;data);
        print(np-&gt;right);
    }
}

int main() {
    int T = 1000; //test case 1000 nodes
    int data, node_id;
    //printf("Input number of nodes:");
    //scanf("%d", &amp;T);
    node *root = NULL;
    srand (time (NULL));
    while (T-- &gt; 0) {
        //printf("Input data. %d:", T);
        //scanf("%d %d", &amp;data, &amp;node_id);
        int r = rand() % 1000;
        int r2 = rand() % 1000;
        root = insert_node(root, r, r2);
    }
    print(root);
    printf("\n");
    printf("Find data at node:", T);
    scanf("%d", &amp;T);
    printf("node data %d", find_node_data(root, T)-&gt;data);
    return 0;
}
This is a binary search tree.
Do not cast the return value of malloc. It serves no purpose, and may mask a serious bug (in case stdlib.h is not included).
Lookup is usually implemented iteratively:

while (root) {
    if (root-&gt;id == id) {
        break;
    }
    root = (root-&gt;id &lt; id)? root-&gt;right: root-&gt;left;
}
return root;

insert_node may use less indentation. Early return makes else unnecessary:

node *insert_node(node *root, int data, int node_id) {
    if (root == NULL)
        return newNode(data, node_id);
    node *cur;
    if (node_id &lt; root-&gt;node_id) {
        cur = insert_node(root-&gt;left, data, node_id);
        root-&gt;left = cur;
    } else if (node_id &gt; root-&gt;node_id) {
        cur = insert_node(root-&gt;right, data, node_id);
        root-&gt;right = cur;
    }
    return root;
}

You may want to inform the caller that the insertion failed due to id already present.