161 lines
4.8 KiB
C
161 lines
4.8 KiB
C
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
// Structure for a binary tree node containing data and pointers to left and right children
|
||
|
struct node {
|
||
|
int data;
|
||
|
struct node *left, *right;
|
||
|
};
|
||
|
|
||
|
// Function to create a new node with given value
|
||
|
// Allocates memory and initializes node with NULL children
|
||
|
struct node* createNode(int value) {
|
||
|
struct node* newNode = malloc(sizeof(struct node));
|
||
|
newNode->data = value;
|
||
|
newNode->left = NULL;
|
||
|
newNode->right = NULL;
|
||
|
return newNode;
|
||
|
}
|
||
|
|
||
|
// Function to insert a new value into the BST
|
||
|
// Recursively finds correct position and inserts new node while maintaining BST properties
|
||
|
struct node* insert(struct node* root, int value) {
|
||
|
if (root == NULL) return createNode(value);
|
||
|
if (value < root->data)
|
||
|
root->left = insert(root->left, value);
|
||
|
else if (value > root->data)
|
||
|
root->right = insert(root->right, value);
|
||
|
return root;
|
||
|
}
|
||
|
|
||
|
// Function to find the node with minimum value in a BST
|
||
|
// Used as a helper function for deletion
|
||
|
struct node* minValueNode(struct node* node) {
|
||
|
struct node* current = node;
|
||
|
while (current && current->left != NULL)
|
||
|
current = current->left;
|
||
|
return current;
|
||
|
}
|
||
|
|
||
|
// Function to delete a node with given value from BST
|
||
|
// Handles three cases: no child, one child, and two children
|
||
|
struct node* deleteNode(struct node* root, int value) {
|
||
|
if (root == NULL) return root;
|
||
|
if (value < root->data)
|
||
|
root->left = deleteNode(root->left, value);
|
||
|
else if (value > root->data)
|
||
|
root->right = deleteNode(root->right, value);
|
||
|
else {
|
||
|
// Node with only one child or no child
|
||
|
if (root->left == NULL) {
|
||
|
struct node* temp = root->right;
|
||
|
free(root);
|
||
|
return temp;
|
||
|
}
|
||
|
else if (root->right == NULL) {
|
||
|
struct node* temp = root->left;
|
||
|
free(root);
|
||
|
return temp;
|
||
|
}
|
||
|
// Node with two children: Get the inorder successor (smallest in the right subtree)
|
||
|
struct node* temp = minValueNode(root->right);
|
||
|
root->data = temp->data;
|
||
|
root->right = deleteNode(root->right, temp->data);
|
||
|
}
|
||
|
return root;
|
||
|
}
|
||
|
|
||
|
// Function to perform inorder traversal of BST
|
||
|
// Visits left subtree, root, then right subtree (LNR)
|
||
|
void inorder(struct node* root) {
|
||
|
if (root != NULL) {
|
||
|
inorder(root->left);
|
||
|
printf("%d ", root->data);
|
||
|
inorder(root->right);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Function to perform preorder traversal of BST
|
||
|
// Visits root, left subtree, then right subtree (NLR)
|
||
|
void preorder(struct node* root) {
|
||
|
if (root != NULL) {
|
||
|
printf("%d ", root->data);
|
||
|
preorder(root->left);
|
||
|
preorder(root->right);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Function to perform postorder traversal of BST
|
||
|
// Visits left subtree, right subtree, then root (LRN)
|
||
|
void postorder(struct node* root) {
|
||
|
if (root != NULL) {
|
||
|
postorder(root->left);
|
||
|
postorder(root->right);
|
||
|
printf("%d ", root->data);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Function to search for a key in BST
|
||
|
// Returns pointer to node if found, NULL if not found
|
||
|
struct node* search(struct node* root, int key) {
|
||
|
if (root == NULL || root->data == key)
|
||
|
return root;
|
||
|
if (root->data < key)
|
||
|
return search(root->right, key);
|
||
|
return search(root->left, key);
|
||
|
}
|
||
|
|
||
|
// Main function providing menu-driven interface for BST operations
|
||
|
int main() {
|
||
|
struct node* root = NULL;
|
||
|
int choice, value;
|
||
|
|
||
|
while(1) {
|
||
|
printf("\n1. Insert\n2. Delete\n3. Inorder\n4. Preorder\n");
|
||
|
printf("5. Postorder\n6. Search\n7. Exit\n");
|
||
|
printf("Enter your choice: ");
|
||
|
scanf("%d", &choice);
|
||
|
|
||
|
switch(choice) {
|
||
|
case 1:
|
||
|
printf("Enter value to insert: ");
|
||
|
scanf("%d", &value);
|
||
|
root = insert(root, value);
|
||
|
break;
|
||
|
case 2:
|
||
|
printf("Enter value to delete: ");
|
||
|
scanf("%d", &value);
|
||
|
root = deleteNode(root, value);
|
||
|
break;
|
||
|
case 3:
|
||
|
printf("Inorder traversal: ");
|
||
|
inorder(root);
|
||
|
printf("\n");
|
||
|
break;
|
||
|
case 4:
|
||
|
printf("Preorder traversal: ");
|
||
|
preorder(root);
|
||
|
printf("\n");
|
||
|
break;
|
||
|
case 5:
|
||
|
printf("Postorder traversal: ");
|
||
|
postorder(root);
|
||
|
printf("\n");
|
||
|
break;
|
||
|
case 6:
|
||
|
printf("Enter value to search: ");
|
||
|
scanf("%d", &value);
|
||
|
if(search(root, value) != NULL)
|
||
|
printf("Found\n");
|
||
|
else
|
||
|
printf("Not Found\n");
|
||
|
break;
|
||
|
case 7:
|
||
|
exit(0);
|
||
|
default:
|
||
|
printf("Invalid choice!\n");
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|