|
| 1 | +/* |
| 2 | + * Project 20: Binary Search Tree (BST) Implementation |
| 3 | + * Author: Bocaletto Luca |
| 4 | + * Date: 2025-06-22 |
| 5 | + * GitHub: bocaletto-luca |
| 6 | + * |
| 7 | + * Description: |
| 8 | + * This program implements a binary search tree (BST) with the following operations: |
| 9 | + * - Insertion: Add new nodes while preserving the BST property, where all nodes in the left subtree |
| 10 | + * contain values less than the parent node, and all nodes in the right subtree contain values greater. |
| 11 | + * - Searching: Locate a node with a specific value in the BST. |
| 12 | + * - Traversals: |
| 13 | + * - In-order Traversal: Visits nodes in ascending order. |
| 14 | + * - Pre-order Traversal: Visits the root before its subtrees. |
| 15 | + * - Post-order Traversal: Visits the root after its subtrees. |
| 16 | + * |
| 17 | + * Key Concepts: |
| 18 | + * - Dynamic memory allocation using malloc(). |
| 19 | + * - Recursion for tree operations. |
| 20 | + * - Maintaining the BST property during insertions and searches. |
| 21 | + */ |
| 22 | + |
| 23 | +#include <stdio.h> |
| 24 | +#include <stdlib.h> |
| 25 | + |
| 26 | +// Define the structure for a BST node. |
| 27 | +typedef struct Node { |
| 28 | + int data; // Data stored in the node. |
| 29 | + struct Node* left; // Pointer to the left child. |
| 30 | + struct Node* right; // Pointer to the right child. |
| 31 | +} Node; |
| 32 | + |
| 33 | +// Function: createNode |
| 34 | +// -------------------- |
| 35 | +// Allocates a new node with the given data and initializes its pointers to NULL. |
| 36 | +Node* createNode(int data) { |
| 37 | + Node* newNode = (Node*)malloc(sizeof(Node)); |
| 38 | + if (newNode == NULL) { |
| 39 | + printf("Memory allocation error\n"); |
| 40 | + exit(EXIT_FAILURE); |
| 41 | + } |
| 42 | + newNode->data = data; |
| 43 | + newNode->left = newNode->right = NULL; |
| 44 | + return newNode; |
| 45 | +} |
| 46 | + |
| 47 | +// Function: insert |
| 48 | +// ---------------- |
| 49 | +// Recursively inserts a new value into the BST while preserving its properties. |
| 50 | +// Parameters: |
| 51 | +// root - The root node of the BST (can be NULL for an empty tree). |
| 52 | +// data - The value to insert. |
| 53 | +// Returns the new root of the BST. |
| 54 | +Node* insert(Node* root, int data) { |
| 55 | + if (root == NULL) { |
| 56 | + // Found the correct position for insertion. |
| 57 | + return createNode(data); |
| 58 | + } |
| 59 | + if (data < root->data) { |
| 60 | + // Insert into the left subtree if the data is less than the current node's value. |
| 61 | + root->left = insert(root->left, data); |
| 62 | + } else if (data > root->data) { |
| 63 | + // Insert into the right subtree if the data is greater than the current node's value. |
| 64 | + root->right = insert(root->right, data); |
| 65 | + } |
| 66 | + // Duplicate values are not inserted; return the unchanged node. |
| 67 | + return root; |
| 68 | +} |
| 69 | + |
| 70 | +// Function: searchNode |
| 71 | +// -------------------- |
| 72 | +// Searches for a node with the specified value in the BST. |
| 73 | +// Parameters: |
| 74 | +// root - The root node of the BST. |
| 75 | +// data - The value to search for. |
| 76 | +// Returns a pointer to the node if found; otherwise, returns NULL. |
| 77 | +Node* searchNode(Node* root, int data) { |
| 78 | + if (root == NULL || root->data == data) { |
| 79 | + return root; |
| 80 | + } |
| 81 | + if (data < root->data) { |
| 82 | + return searchNode(root->left, data); |
| 83 | + } else { |
| 84 | + return searchNode(root->right, data); |
| 85 | + } |
| 86 | +} |
| 87 | + |
| 88 | +// Function: inorderTraversal |
| 89 | +// -------------------------- |
| 90 | +// Performs an in-order traversal (left, root, right) of the BST and prints the node values. |
| 91 | +// This traversal prints the values in sorted order. |
| 92 | +void inorderTraversal(Node* root) { |
| 93 | + if (root != NULL) { |
| 94 | + inorderTraversal(root->left); |
| 95 | + printf("%d ", root->data); |
| 96 | + inorderTraversal(root->right); |
| 97 | + } |
| 98 | +} |
| 99 | + |
| 100 | +// Function: preorderTraversal |
| 101 | +// --------------------------- |
| 102 | +// Performs a pre-order traversal (root, left, right) of the BST and prints the node values. |
| 103 | +void preorderTraversal(Node* root) { |
| 104 | + if (root != NULL) { |
| 105 | + printf("%d ", root->data); |
| 106 | + preorderTraversal(root->left); |
| 107 | + preorderTraversal(root->right); |
| 108 | + } |
| 109 | +} |
| 110 | + |
| 111 | +// Function: postorderTraversal |
| 112 | +// ---------------------------- |
| 113 | +// Performs a post-order traversal (left, right, root) of the BST and prints the node values. |
| 114 | +void postorderTraversal(Node* root) { |
| 115 | + if (root != NULL) { |
| 116 | + postorderTraversal(root->left); |
| 117 | + postorderTraversal(root->right); |
| 118 | + printf("%d ", root->data); |
| 119 | + } |
| 120 | +} |
| 121 | + |
| 122 | +// Main function: Demonstrates BST operations. |
| 123 | +int main(void) { |
| 124 | + Node* root = NULL; // Start with an empty BST. |
| 125 | + |
| 126 | + // Insert elements into the BST. |
| 127 | + int elements[] = {50, 30, 70, 20, 40, 60, 80}; |
| 128 | + int n = sizeof(elements) / sizeof(elements[0]); |
| 129 | + for (int i = 0; i < n; i++) { |
| 130 | + root = insert(root, elements[i]); |
| 131 | + } |
| 132 | + |
| 133 | + // Display the BST using different traversals. |
| 134 | + printf("In-order Traversal (Sorted Order):\n"); |
| 135 | + inorderTraversal(root); |
| 136 | + printf("\n"); |
| 137 | + |
| 138 | + printf("Pre-order Traversal:\n"); |
| 139 | + preorderTraversal(root); |
| 140 | + printf("\n"); |
| 141 | + |
| 142 | + printf("Post-order Traversal:\n"); |
| 143 | + postorderTraversal(root); |
| 144 | + printf("\n"); |
| 145 | + |
| 146 | + // Search for a specific value in the BST. |
| 147 | + int searchValue = 40; |
| 148 | + Node* result = searchNode(root, searchValue); |
| 149 | + if (result != NULL) { |
| 150 | + printf("Node with value %d found in the BST.\n", searchValue); |
| 151 | + } else { |
| 152 | + printf("Node with value %d not found in the BST.\n", searchValue); |
| 153 | + } |
| 154 | + |
| 155 | + // Note: In a complete implementation, you should free all allocated memory |
| 156 | + // to prevent memory leaks. For brevity, the deallocation is not shown here. |
| 157 | + |
| 158 | + return 0; |
| 159 | +} |
0 commit comments