Binary Search Tree Program In C

4 min read

A binary search tree program in C provides an efficient way to store, retrieve, and manipulate sorted data using a hierarchical structure. In this guide you will learn how to build a complete binary search tree (BST) in C, understand each operation, and see a full implementation that you can compile and run.

What Is a Binary Search Tree?

A binary search tree is a node‑based data structure where each node contains a key and optionally associated data. The tree follows a strict ordering rule: for any node, all keys in its left subtree are smaller than the node's key, and all keys in its right subtree are larger. This property enables fast lookup, insertion, and deletion when the tree is balanced No workaround needed..

Why Use a BST?

  • Fast average‑case performance – operations such as search, insert, and delete run in O(log n) time on average.
  • Ordered traversal – an in‑order walk yields keys in

Node Definition

Each element of the tree is represented by a struct that holds the key, a pointer to associated data (if needed), and links to the left and right children:

typedef struct BSTNode {
    int key;                     // key used for ordering
    void *value;                 // optional payload; can be NULL
    struct BSTNode *left;
    struct BSTNode *right;
} BSTNode;

Helper: Creating a New Node

Allocating memory and initializing fields keeps the insertion logic clean:

static BSTNode *createNode(int key, void *value)
{
    BSTNode *node = malloc(sizeof *node);
    if (!node) {
        perror("malloc");
        exit(EXIT_FAILURE);
    }
    node->key   = key;
    node->value = value;
    node->left  = node->right = NULL;
    return node;
}

Insertion

To insert a key we walk down the tree comparing with the current node’s key, then attach the new node as a leaf where the appropriate child pointer is NULL. Duplicates can be handled either by ignoring them or storing a count; here we ignore duplicates Still holds up..

BSTNode *bstInsert(BSTNode *root, int key, void *value)
{
    if (root == NULL)
        return createNode(key, value);

    if (key < root->key)
        root->left  = bstInsert(root->left,  key, value);
    else if (key > root->key)
        root->right = bstInsert(root->right, key, value);
    /* key == root->key → duplicate; do nothing */

    return root;
}

Search

Search follows the same comparison path, returning the node (or its payload) when the key matches, or NULL if the key is absent Simple as that..

BSTNode *bstSearch(const BSTNode *root, int key)
{
    if (root == NULL || root->key == key)
        return (BSTNode *)root;   // cast away const for convenience

    if (key < root->key)
        return bstSearch(root->left,  key);
    else
        return bstSearch(root->right, key);
}

Finding Minimum and Maximum

These utilities are handy for deletion and for ordered traversal extremes Took long enough..

static BSTNode *bstMin(BSTNode *node)
{
    while (node && node->left)
        node = node->left;
    return node;
}

static BSTNode *bstMax(BSTNode *node)
{
    while (node && node->right)
        node = node->right;
    return node;
}

Deletion

Deletion must preserve the BST ordering. Three cases arise:

  1. Leaf node – simply free it.
  2. One child – bypass the node.
  3. Two children – replace the node’s key/value with its in‑order successor (the smallest node in the right subtree) and then delete that successor.
BSTNode *bstDelete(BSTNode *root, int key)
{
    if (root == NULL) return NULL;

    if (key < root->key)
        root->left = bstDelete(root->left,  key);
    else if (key > root->key)
        root->right = bstDelete(root->right, key);
    else { /* found the node to delete */
        if (root->left == NULL) {
            BSTNode *temp = root->right;
            free(root);
            return temp;
        } else if (root->right == NULL) {
            BSTNode *temp = root->left;
            free(root);
            return temp;
        }

        /* node with two children: get inorder successor */
        BSTNode *succ = bstMin(root->right);
        root->key   = succ->key;
        root->value = succ->value;
        /* Delete the successor */
        root->right = bstDelete(root->right, succ->key);
    }
    return root;
}

Traversals

In‑order, pre‑order, and post‑order walks are implemented recursively; they can easily be adapted to iterative versions using an explicit stack.

void inorder(const BSTNode *node)
{
    if (!node) return;
    inorder(node->left);
    printf("%d ", node->key);
    inorder(node->right);
}

void preorder(const BSTNode *node)
{
    if (!node) return;
    printf("%d ", node->key);
    preorder(node->left);
    preorder(node->right);
}

void postorder(const BSTNode *node)
{
    if (!node) return;
    postorder(node->left);
    postorder(node->right);
    printf("%d ", node->key);
}

Full Program Example

Putting the pieces together yields a compilable demo that inserts a few numbers, searches, deletes, and prints the tree in order Simple as that..

#include 
#include 

/* ---- Node

```c
#include 
#include 

/* ---- Node definition ---- */
typedef struct BSTNode {
    int key;
    int value;
    struct BSTNode *left;
    struct BSTNode *right;
} BSTNode;

/* ---- Insertion ---- */
BSTNode *bstInsert(BSTNode *root, int key, int value)
{
    if (root == NULL) {
        root = (BSTNode *)malloc(sizeof(BSTNode));
        root->key   = key;
        root->value = value;
        root->left  = root->right = NULL;
    } else if (key < root->key) {
        root->left  = bstInsert(root->left,  key, value);
Up Next

Latest Additions

Explore More

Stay a Little Longer

Thank you for reading about Binary Search Tree Program In C. We hope the information has been useful. Feel free to contact us if you have any questions. See you next time — don't forget to bookmark!
⌂ Back to Home