Open In App

C Program for Binary Search Tree

Last Updated : 18 Nov, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

A binary Search Tree is a binary tree where the value of any node is greater than the left subtree and less than the right subtree. In this article, we will discuss Binary Search Trees and various operations on Binary Search trees using C programming language.

Properties of Binary Search Tree

Following are some main properties of the binary search tree in C:

  • All nodes of the left subtree are less than the root node and nodes of the right subtree are greater than the root node.
  • The In-order traversal of binary search trees gives the values in ascending order.
  • All the subtrees of BST hold the same properties.

Example:

binary-search-tree

Binary Search Tree

Binary Tree Structure in C

struct BinaryTreeNode {
  int key;
  struct nodeBinaryTreeNode *left, *right;
};

here,

  • key: It will be the data stored.
  • left: Pointer to the left child.
  • right: Pointer to the right child

Operations on BST C

  • Search in BST
  • Insertion in BST
  • Deletion in BST

1. Search Operation on BST in C

The algorithm for the search operation is:

  1. If the root is NULL or the key of the root matches the target:
    1. Return the current root node.
  2. If the target is greater than the key of the current root:
    1. Recursively call searchNode with the right subtree of the current root and the target.
    2. Return the result of the recursive call.
  3. If the target is smaller than the key of the current root:
    1. Recursively call searchNode with the left subtree of the current root and the target.
    2. Return the result of the recursive call.
  4. If the target is not found in the current subtree, return NULL.

where the target is the key to search for in the tree.

Time Complexity: O(log n)

2. Insertion in BST

The insertNode function inserts a new node with a specific value into a Binary Search Tree while maintaining the binary search tree property.

Algorithm

  1. If the current node is NULL
    1. Return a new node created with the specified value.
  2. If the value is less than the key of the current node:
    1. Recursively call insertNode with the left subtree of the current node and the value.
    2. Update the left child of the current node with the result of the recursive call.
  3. If the value is greater than the key of the current node:
    1. Recursively call insertNode with the right subtree of the current node and the value.
    2. Update the right child of the current node with the result of the recursive call.
  4. Return the current node (the root of the modified tree).

Time Complexity: O(log n)

4. Deletion in BST

There are few cases at the time of deleting a node in BST

a. Deleted node is the leaf node

In this case, simply delete the node from the tree.

Group-115

b. Deleted node has a single child node

In this case, replace the target node with its child (single child) and then delete that child node.

Group-115-(1)

c. Deleted node has two children

In this case, at first, we will find the inorder successor of that node. And then replace the node with the inorder successor. Then remove the inorder successor from its original position.

Group-115-(2)

Algorithm

  1. If the root is NULL:
    1. Return NULL (base case for recursion).
  2. If the value to be deleted (x) is greater than the key of the current root:
    1. Recursively call delete with the right subtree of the current root and the value x.
    2. Update the right child of the current root with the result of the recursive call.
  3. If the value to be deleted (x) is smaller than the key of the current root:
    1. Recursively call delete with the left subtree of the current root and the value x.
    2. Update the left child of the current root with the result of the recursive call.
  4. If the value to be deleted (x) is equal to the key of the current root:
    1. If the current node has no child:
      1. Free the current node.
      2. Return NULL.
    2. If the current node has one child:
      1. Set temp to the non-null child of the current node.
      2. Free the current node.
      3. Return temp.
    3. If the current node has two children:
      1. Find the minimum node in the right subtree (temp).
      2. Replace the key of the current node with the key of temp.
      3. Recursively call delete with the right subtree of the current node and the key of temp.
  5. Return the current node (the root of the modified tree).

Time Complexity: O(log n)

C Program to Implement Binary Search Tree

C




// C program to implement binary search tree
#include <stdio.h>
#include <stdlib.h>
 
// Define a structure for a binary tree node
struct BinaryTreeNode {
    int key;
    struct BinaryTreeNode *left, *right;
};
 
// Function to create a new node with a given value
struct BinaryTreeNode* newNodeCreate(int value)
{
    struct BinaryTreeNode* temp
        = (struct BinaryTreeNode*)malloc(
            sizeof(struct BinaryTreeNode));
    temp->key = value;
    temp->left = temp->right = NULL;
    return temp;
}
 
// Function to search for a node with a specific key in the
// tree
struct BinaryTreeNode*
searchNode(struct BinaryTreeNode* root, int target)
{
    if (root == NULL || root->key == target) {
        return root;
    }
    if (root->key < target) {
        return searchNode(root->right, target);
    }
    return searchNode(root->left, target);
}
 
// Function to insert a node with a specific value in the
// tree
struct BinaryTreeNode*
insertNode(struct BinaryTreeNode* node, int value)
{
    if (node == NULL) {
        return newNodeCreate(value);
    }
    if (value < node->key) {
        node->left = insertNode(node->left, value);
    }
    else if (value > node->key) {
        node->right = insertNode(node->right, value);
    }
    return node;
}
 
// Function to perform post-order traversal
void postOrder(struct BinaryTreeNode* root)
{
    if (root != NULL) {
        postOrder(root->left);
        postOrder(root->right);
        printf(" %d ", root->key);
    }
}
 
// Function to perform in-order traversal
void inOrder(struct BinaryTreeNode* root)
{
    if (root != NULL) {
        inOrder(root->left);
        printf(" %d ", root->key);
        inOrder(root->right);
    }
}
 
// Function to perform pre-order traversal
void preOrder(struct BinaryTreeNode* root)
{
    if (root != NULL) {
        printf(" %d ", root->key);
        preOrder(root->left);
        preOrder(root->right);
    }
}
 
// Function to find the minimum value
struct BinaryTreeNode* findMin(struct BinaryTreeNode* root)
{
    if (root == NULL) {
        return NULL;
    }
    else if (root->left != NULL) {
        return findMin(root->left);
    }
    return root;
}
 
// Function to delete a node from the tree
struct BinaryTreeNode* delete (struct BinaryTreeNode* root,
                               int x)
{
    if (root == NULL)
        return NULL;
 
    if (x > root->key) {
        root->right = delete (root->right, x);
    }
    else if (x < root->key) {
        root->left = delete (root->left, x);
    }
    else {
        if (root->left == NULL && root->right == NULL) {
            free(root);
            return NULL;
        }
        else if (root->left == NULL
                 || root->right == NULL) {
            struct BinaryTreeNode* temp;
            if (root->left == NULL) {
                temp = root->right;
            }
            else {
                temp = root->left;
            }
            free(root);
            return temp;
        }
        else {
            struct BinaryTreeNode* temp
                = findMin(root->right);
            root->key = temp->key;
            root->right = delete (root->right, temp->key);
        }
    }
    return root;
}
 
int main()
{
    // Initialize the root node
    struct BinaryTreeNode* root = NULL;
 
    // Insert nodes into the binary search tree
    root = insertNode(root, 50);
    insertNode(root, 30);
    insertNode(root, 20);
    insertNode(root, 40);
    insertNode(root, 70);
    insertNode(root, 60);
    insertNode(root, 80);
 
    // Search for a node with key 60
    if (searchNode(root, 60) != NULL) {
        printf("60 found");
    }
    else {
        printf("60 not found");
    }
 
    printf("\n");
 
    // Perform post-order traversal
    postOrder(root);
    printf("\n");
 
    // Perform pre-order traversal
    preOrder(root);
    printf("\n");
 
    // Perform in-order traversal
    inOrder(root);
    printf("\n");
 
    // Perform delete the node (70)
    struct BinaryTreeNode* temp = delete (root, 70);
    printf("After Delete: \n");
    inOrder(root);
 
    // Free allocated memory (not done in this code, but
    // good practice in real applications)
 
    return 0;
}


Output

60 found
 20  40  30  60  80  70  50 
 50  30  20  40  70  60  80 
 20  30  40  50  60  70  80 
After Delete: 
 20  30  40  50  60  80 

To know more about Binary Search Tree, refer to the article – Binary Search Tree



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads