diff --git a/DS/C/endsem-omnibus/LL.c b/DS/C/endsem-omnibus/LL.c new file mode 100644 index 0000000..4b2f99c --- /dev/null +++ b/DS/C/endsem-omnibus/LL.c @@ -0,0 +1,221 @@ +#include +#include + +struct Node { + int data; + struct Node* next; +}; + +struct Node* head = NULL; + +void insertAtBeginning(int value) { + struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); + newNode->data = value; + newNode->next = head; + head = newNode; + printf("\nInsertion successful at beginning\n"); +} + +void insertAtEnd(int value) { + struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); + newNode->data = value; + newNode->next = NULL; + + if(head == NULL) { + head = newNode; + return; + } + + struct Node* temp = head; + while(temp->next != NULL) { + temp = temp->next; + } + temp->next = newNode; + printf("\nInsertion successful at end\n"); +} + +void insertAtPosition(int value, int position) { + if(position < 1) { + printf("\nInvalid position\n"); + return; + } + + if(position == 1) { + insertAtBeginning(value); + return; + } + + struct Node* newNode = (struct Node*)malloc(sizeof(struct Node)); + newNode->data = value; + + struct Node* temp = head; + for(int i = 1; i < position-1 && temp != NULL; i++) { + temp = temp->next; + } + + if(temp == NULL) { + printf("\nPosition exceeds list length\n"); + free(newNode); + return; + } + + newNode->next = temp->next; + temp->next = newNode; + printf("\nInsertion successful at position %d\n", position); +} + +void deleteFromBeginning() { + if(head == NULL) { + printf("\nList is empty\n"); + return; + } + struct Node* temp = head; + head = head->next; + free(temp); + printf("\nDeletion successful from beginning\n"); +} + +void deleteFromEnd() { + if(head == NULL) { + printf("\nList is empty\n"); + return; + } + if(head->next == NULL) { + free(head); + head = NULL; + return; + } + struct Node* temp = head; + while(temp->next->next != NULL) { + temp = temp->next; + } + free(temp->next); + temp->next = NULL; + printf("\nDeletion successful from end\n"); +} + +void sortList() { + if(head == NULL || head->next == NULL) { + return; + } + + struct Node *current, *index; + int temp; + + for(current = head; current != NULL; current = current->next) { + for(index = current->next; index != NULL; index = index->next) { + if(current->data > index->data) { + temp = current->data; + current->data = index->data; + index->data = temp; + } + } + } + printf("\nList sorted successfully\n"); +} + +void reverseList() { + struct Node *prev = NULL, *current = head, *next = NULL; + + while(current != NULL) { + next = current->next; + current->next = prev; + prev = current; + current = next; + } + head = prev; + printf("\nList reversed successfully\n"); +} + +void display() { + if(head == NULL) { + printf("\nList is empty\n"); + return; + } + struct Node* temp = head; + printf("\nList elements are: "); + while(temp != NULL) { + printf("%d ", temp->data); + temp = temp->next; + } + printf("\n"); +} + +void search(int value) { + struct Node* temp = head; + int position = 1; + while(temp != NULL) { + if(temp->data == value) { + printf("\nElement %d found at position %d\n", value, position); + return; + } + temp = temp->next; + position++; + } + printf("\nElement %d not found in the list\n", value); +} + +int main() { + int choice, value, position; + + while(1) { + printf("\n1. Insert at beginning"); + printf("\n2. Insert at end"); + printf("\n3. Insert at specific position"); + printf("\n4. Delete from beginning"); + printf("\n5. Delete from end"); + printf("\n6. Sort list"); + printf("\n7. Reverse list"); + printf("\n8. Display"); + printf("\n9. Search"); + printf("\n10. Exit"); + printf("\nEnter your choice: "); + scanf("%d", &choice); + + switch(choice) { + case 1: + printf("\nEnter value to insert: "); + scanf("%d", &value); + insertAtBeginning(value); + break; + case 2: + printf("\nEnter value to insert: "); + scanf("%d", &value); + insertAtEnd(value); + break; + case 3: + printf("\nEnter value to insert: "); + scanf("%d", &value); + printf("\nEnter position: "); + scanf("%d", &position); + insertAtPosition(value, position); + break; + case 4: + deleteFromBeginning(); + break; + case 5: + deleteFromEnd(); + break; + case 6: + sortList(); + break; + case 7: + reverseList(); + break; + case 8: + display(); + break; + case 9: + printf("\nEnter value to search: "); + scanf("%d", &value); + search(value); + break; + case 10: + printf("\nExiting program\n"); + exit(0); + default: + printf("\nInvalid choice\n"); + } + } + return 0; +} diff --git a/DS/C/endsem-omnibus/bst.c b/DS/C/endsem-omnibus/bst.c new file mode 100644 index 0000000..1daa874 --- /dev/null +++ b/DS/C/endsem-omnibus/bst.c @@ -0,0 +1,160 @@ +#include +#include + +// 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; +} diff --git a/DS/C/endsem-omnibus/bstiterative.c b/DS/C/endsem-omnibus/bstiterative.c new file mode 100644 index 0000000..0d10a91 --- /dev/null +++ b/DS/C/endsem-omnibus/bstiterative.c @@ -0,0 +1,172 @@ +#include +#include + +// BST Node structure +typedef struct Node { + int data; + struct Node *left; + struct Node *right; +} Node; + +// Function to create a new node +Node* createNode(int value) { + Node* newNode = (Node*)malloc(sizeof(Node)); + newNode->data = value; + newNode->left = NULL; + newNode->right = NULL; + return newNode; +} + +// Iterative Insert function +Node* insert(Node* root, int value) { + // If tree is empty, create root node + if (root == NULL) return createNode(value); + + Node* current = root; + while (1) { + // If value is less than current node + if (value < current->data) { + if (current->left == NULL) { + current->left = createNode(value); + break; + } + current = current->left; + } + // If value is greater than current node + else if (value > current->data) { + if (current->right == NULL) { + current->right = createNode(value); + break; + } + current = current->right; + } + // If value already exists + else break; + } + return root; +} + +// Iterative Search function +Node* search(Node* root, int value) { + Node* current = root; + + while (current != NULL) { + // If value found + if (value == current->data) + return current; + // If value is less than current node + else if (value < current->data) + current = current->left; + // If value is greater than current node + else + current = current->right; + } + return NULL; +} + +// Function to find minimum value node +Node* findMin(Node* root) { + if (root == NULL) return NULL; + + Node* current = root; + while (current->left != NULL) + current = current->left; + return current; +} + +// Iterative Delete function +Node* delete(Node* root, int value) { + if (root == NULL) return root; + + Node* current = root; + Node* parent = NULL; + + // Find the node to delete and its parent + while (current != NULL && current->data != value) { + parent = current; + if (value < current->data) + current = current->left; + else + current = current->right; + } + + // If value not found + if (current == NULL) return root; + + // Case 1: Node has no children + if (current->left == NULL && current->right == NULL) { + if (current != root) { + if (parent->left == current) + parent->left = NULL; + else + parent->right = NULL; + } + else + root = NULL; + free(current); + } + + // Case 2: Node has one child + else if (current->left == NULL || current->right == NULL) { + Node* child = (current->left) ? current->left : current->right; + if (current != root) { + if (parent->left == current) + parent->left = child; + else + parent->right = child; + } + else + root = child; + free(current); + } + + // Case 3: Node has two children + else { + Node* successor = findMin(current->right); + int successorData = successor->data; + delete(root, successor->data); + current->data = successorData; + } + + return root; +} + +// Iterative Inorder traversal +void inorderTraversal(Node* root) { + if (root == NULL) return; + + Node* stack[1000]; + int top = -1; + Node* current = root; + + while (current != NULL || top != -1) { + // Reach the leftmost node + while (current != NULL) { + stack[++top] = current; + current = current->left; + } + + current = stack[top--]; + printf("%d ", current->data); + current = current->right; + } +} + +// Iterative Level Order traversal +void levelOrder(Node* root) { + if (root == NULL) return; + + Node* queue[1000]; + int front = 0, rear = 0; + queue[rear++] = root; + + while (front < rear) { + Node* current = queue[front++]; + printf("%d ", current->data); + + if (current->left != NULL) + queue[rear++] = current->left; + if (current->right != NULL) + queue[rear++] = current->right; + } +} diff --git a/DS/C/endsem-omnibus/circq.c b/DS/C/endsem-omnibus/circq.c new file mode 100644 index 0000000..784f721 --- /dev/null +++ b/DS/C/endsem-omnibus/circq.c @@ -0,0 +1,101 @@ +#include +#include +#define MAX 5 + +int queue[MAX]; +int front = -1; +int rear = -1; + +// Different from normal queue: Need to check if (rear+1)%MAX == front for full condition +int isFull() { + if((rear + 1) % MAX == front) + return 1; + return 0; +} + +// Different from normal queue: Both front and rear can wrap around to 0 +int isEmpty() { + if(front == -1) + return 1; + return 0; +} + +void enqueue() { + int item; + if(isFull()) { + printf("\nQueue is Full!!"); + } + else { + printf("\nEnter element to insert: "); + scanf("%d", &item); + // Different from normal queue: rear wraps around using modulo + if(front == -1) { + front = rear = 0; + } + else { + rear = (rear + 1) % MAX; + } + queue[rear] = item; + printf("\nElement inserted successfully!"); + } +} + +void dequeue() { + if(isEmpty()) { + printf("\nQueue is Empty!!"); + } + else { + printf("\nDeleted element is: %d", queue[front]); + // Different from normal queue: front wraps around using modulo + if(front == rear) { + front = rear = -1; + } + else { + front = (front + 1) % MAX; + } + } +} + +void display() { + int i; + if(isEmpty()) { + printf("\nQueue is Empty!!"); + } + else { + printf("\nQueue elements are: "); + // Different from normal queue: Need to use modulo to wrap around while displaying + for(i = front; i != rear; i = (i + 1) % MAX) { + printf("%d ", queue[i]); + } + printf("%d", queue[i]); + } +} + +int main() { + int choice; + while(1) { + printf("\n\n1. Insert"); + printf("\n2. Delete"); + printf("\n3. Display"); + printf("\n4. Exit"); + printf("\nEnter your choice: "); + scanf("%d", &choice); + + switch(choice) { + case 1: + enqueue(); + break; + case 2: + dequeue(); + break; + case 3: + display(); + break; + case 4: + exit(0); + default: + printf("\nInvalid choice!!"); + } + } + return 0; +} diff --git a/DS/C/endsem-omnibus/heap.c b/DS/C/endsem-omnibus/heap.c new file mode 100644 index 0000000..b499862 --- /dev/null +++ b/DS/C/endsem-omnibus/heap.c @@ -0,0 +1,125 @@ +#include +#include + +#define MAX_SIZE 100 + +// Structure for Min Heap +typedef struct { + int arr[MAX_SIZE]; + int size; +} MinHeap; + +// Structure for Stack +typedef struct { + int arr[MAX_SIZE]; + int top; +} Stack; + +// Initialize empty stack +void initStack(Stack *s) { + s->top = -1; +} + +// Check if stack is empty +int isEmpty(Stack *s) { + return s->top == -1; +} + +// Check if stack is full +int isFull(Stack *s) { + return s->top == MAX_SIZE - 1; +} + +// Push element onto stack +void push(Stack *s, int value) { + if(isFull(s)) { + printf("Stack Overflow\n"); + return; + } + s->arr[++s->top] = value; +} + +// Pop element from stack +int pop(Stack *s) { + if(isEmpty(s)) { + printf("Stack Underflow\n"); + return -1; + } + return s->arr[s->top--]; +} + +// Initialize Min Heap +void initMinHeap(MinHeap *heap) { + heap->size = 0; +} + +// Helper function to swap elements +void swap(int *a, int *b) { + int temp = *a; + *a = *b; + *b = temp; +} + +// Heapify function +void heapify(MinHeap *heap, int index) { + int smallest = index; + int left = 2 * index + 1; + int right = 2 * index + 2; + + if(left < heap->size && heap->arr[left] < heap->arr[smallest]) + smallest = left; + + if(right < heap->size && heap->arr[right] < heap->arr[smallest]) + smallest = right; + + if(smallest != index) { + swap(&heap->arr[index], &heap->arr[smallest]); + heapify(heap, smallest); + } +} + +// Convert stack to min heap +void stackToHeap(Stack *s, MinHeap *heap) { + // Copy stack elements to heap array + heap->size = s->top + 1; + for(int i = 0; i <= s->top; i++) { + heap->arr[i] = s->arr[i]; + } + + // Heapify all non-leaf nodes + for(int i = (heap->size/2) - 1; i >= 0; i--) { + heapify(heap, i); + } +} + +int main() { + Stack stack; + MinHeap heap; + + initStack(&stack); + initMinHeap(&heap); + + // Push some elements onto stack + push(&stack, 5); + push(&stack, 3); + push(&stack, 8); + push(&stack, 1); + push(&stack, 2); + + printf("Original Stack: "); + for(int i = 0; i <= stack.top; i++) { + printf("%d ", stack.arr[i]); + } + printf("\n"); + + // Convert stack to min heap + stackToHeap(&stack, &heap); + + printf("After Heapifying: "); + for(int i = 0; i < heap.size; i++) { + printf("%d ", heap.arr[i]); + } + printf("\n"); + + return 0; +}