0% found this document useful (0 votes)
14 views86 pages

Ds Lab Manual

The document contains multiple exercises focusing on data structures in C, including array manipulation, linked list implementation, and applications. It provides source code for reversing arrays, searching techniques (linear and binary), sorting algorithms (bubble sort), and linked list operations such as insertion, deletion, and reversal. Additionally, it covers linked list applications like removing duplicates and representing polynomials.

Uploaded by

bharathisatya510
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
14 views86 pages

Ds Lab Manual

The document contains multiple exercises focusing on data structures in C, including array manipulation, linked list implementation, and applications. It provides source code for reversing arrays, searching techniques (linear and binary), sorting algorithms (bubble sort), and linked list operations such as insertion, deletion, and reversal. Additionally, it covers linked list applications like removing duplicates and representing polynomials.

Uploaded by

bharathisatya510
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 86

Exercise 1: Array Manipulation

i) Write a program to reverse an array.


Source Code:
#include <stdio.h>

// Function to reverse the array


void reverseArray(int arr[], int start, int end) {
int temp;
while (start < end) {
// Swapping elements
temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
start++;
end--;
}
}

// Function to print the array


void printArray(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}

int main() {
int arr[] = {1, 2, 3, 4, 5};
int n = sizeof(arr) / sizeof(arr[0]);
printf("Original array: ");
printArray(arr, n);

// Reverse the array


reverseArray(arr, 0, n - 1);

printf("Reversed array: ");


printArray(arr, n);

return 0;
}
Output:

ii) C Programs to implement the Searching Techniques-Linear & Binary Search


Source Code:
Linear Search with User Input:

#include <stdio.h>

int linearSearch(int arr[], int n, int key) {


for (int i = 0; i < n; i++) {
if (arr[i] == key)
return i; // return the index where key is found
}
return -1; // return -1 if key is not found
}

int main() {
int n, key;
printf("Enter the number of elements in the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter %d elements:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
printf("Enter the element to search: ");
scanf("%d", &key);
int result = linearSearch(arr, n, key);
if (result == -1)
printf("Element %d is not present in the array\n", key);
else
printf("Element %d is present at index %d\n", key, result);
return 0;
}
Output:
Source Code:
Binary Search with User Input:

#include <stdio.h>

int binarySearch(int arr[], int l, int r, int key) {


while (l <= r) {
int mid = l + (r - l) / 2;
if (arr[mid] == key)
return mid; // return the index where key is found
if (arr[mid] < key)
l = mid + 1; // if key is greater, search in right half
else
r = mid - 1; // if key is smaller, search in left half
}
return -1; // return -1 if key is not found
}

int main() {
int n, key;
printf("Enter the number of elements in the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter %d elements in sorted order:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}
printf("Enter the element to search: ");
scanf("%d", &key);
int result = binarySearch(arr, 0, n - 1, key);
if (result == -1)
printf("Element %d is not present in the array\n", key);
else
printf("Element %d is present at index %d\n", key, result);
return 0;
}
Output:

iii) C Programs to implement Sorting Techniques-Bubble, Selection and Insertion Sort


Source Code:

Bubble Sort with User Input:

#include <stdio.h>

void bubbleSort(int arr[], int n) {


for (int i = 0; i < n - 1; i++) {
for (int j = 0; j < n - i - 1; j++) {
if (arr[j] > arr[j + 1]) {
// Swap arr[j] and arr[j+1]
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}

int main() {
int n;
printf("Enter the number of elements in the array: ");
scanf("%d", &n);
int arr[n];
printf("Enter %d elements:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

bubbleSort(arr, n);

printf("Sorted array in ascending order:\n");


for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
Output:
Exercise 2: Linked List Implementation
i) Implement a singly linked list and perform insertion and deletion operations.
Source code:
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node in the linked list


struct Node {
int data;
struct Node* next;
};

// Function to insert a new node at the beginning of the linked list


void insert(struct Node** head_ref, int new_data) {
// Allocate memory for new node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
// Assign data to new node
new_node->data = new_data;
// Make next of new node as head
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}

// Function to delete a node from the linked list


void deleteNode(struct Node **head_ref, int key) {
// Store head node
struct Node* temp = *head_ref, *prev = NULL;
// If head node itself holds the key to be deleted
if (temp != NULL && temp->data == key) {
*head_ref = temp->next; // Change head
free(temp); // Free old head
return;
}

// Search for the key to be deleted, keep track of the previous node as we need to change
'prev->next'
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}

// If key was not present in linked list


if (temp == NULL) return;

// Unlink the node from linked list


prev->next = temp->next;

// Free memory
free(temp);
}

// Function to print the linked list


void printList(struct Node* node) {
printf("Linked List: ");
if (node == NULL) {
printf("List is empty.\n");
return;
}
while (node != NULL) {
printf("%d -> ", node->data);
node = node->next;
}
printf("NULL\n");
}
// Main function
int main() {
struct Node* head = NULL;
int choice, data;
while (1) {
printList(head);
printf("\n1. Insert\n");
printf("2. Delete\n");
printf("3. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch (choice) {
case 1:
printf("Enter data to insert: ");
scanf("%d", &data);
insert(&head, data);
printf("Node with data %d inserted.\n", data);
break;
case 2:
printf("Enter data to delete: ");
scanf("%d", &data);
deleteNode(&head, data);
printf("Node with data %d deleted.\n", data);
break;
case 3:
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}

return 0;
}
Output:
ii) Develop a program to reverse a linked list iteratively and recursively.
Source Code:
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node in the linked list


struct Node {
int data;
struct Node* next;
};

// Function to insert a new node at the beginning of the linked list


void insert(struct Node** head_ref, int new_data) {
// Allocate memory for new node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
// Assign data to new node
new_node->data = new_data;
// Make next of new node as head
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}

// Function to print the linked list


void printList(struct Node* node) {
printf("Linked List: ");
if (node == NULL) {
printf("List is empty.\n");
return;
}
while (node != NULL) {
printf("%d -> ", node->data);
node = node->next;
}
printf("NULL\n");
}

// Function to reverse the linked list iteratively


void reverseIterative(struct Node** head_ref) {
struct Node *prev = NULL, *current = *head_ref, *next;
while (current != NULL) {
next = current->next; // Store next node
current->next = prev; // Reverse current node's pointer
prev = current; // Move pointers one position ahead
current = next;
}
*head_ref = prev; // Set head to the last node
}

// Function to reverse the linked list recursively


void reverseRecursive(struct Node** head_ref) {
struct Node* first;
struct Node* rest;

// Empty list or list with single node


if (*head_ref == NULL || (*head_ref)->next == NULL) {
return;
}
// Separating the first node from the rest of the list
first = *head_ref;
rest = first->next;

// Reverse the rest of the list


reverseRecursive(&rest);

// Fixing the first node


first->next->next = first;
first->next = NULL;

// Adjusting the head pointer


*head_ref = rest;
}

// Main function
int main() {
struct Node* head = NULL;
int choice, data;

while (1) {
printf("\n1. Insert\n");
printf("2. Reverse Iteratively\n");
printf("3. Reverse Recursively\n");
printf("4. Print List\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter data to insert: ");
scanf("%d", &data);
insert(&head, data);
printf("Node with data %d inserted.\n", data);
break;
case 2:
reverseIterative(&head);
printf("List reversed iteratively.\n");
break;
case 3:
reverseRecursive(&head);
printf("List reversed recursively.\n");
break;
case 4:
printList(head);
break;
case 5:
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}

return 0;
}
Output:

iii) Solve problems involving linked list traversal and manipulation.


Source Code:
#include <stdio.h>
#include <stdlib.h>
// Define the structure for a node in the linked list
struct Node {
int data;
struct Node* next;
};
// Function to insert a new node at the beginning of the linked list
void insert(struct Node** head_ref, int new_data) {
// Allocate memory for new node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
// Assign data to new node
new_node->data = new_data;
// Make next of new node as head
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}

// Function to delete a node from the linked list


void deleteNode(struct Node** head_ref, int key) {
struct Node* temp = *head_ref, *prev;

// If the head node itself holds the key to be deleted


if (temp != NULL && temp->data == key) {
*head_ref = temp->next; // Change head
free(temp); // Free old head
return;
}

// Search for the key to be deleted, keep track of the previous node
while (temp != NULL && temp->data != key) {
prev = temp;
temp = temp->next;
}
// If the key was not present in the linked list
if (temp == NULL) return;

// Unlink the node from the linked list


prev->next = temp->next;

// Free memory
free(temp);
}

// Function to print the linked list


void printList(struct Node* node) {
printf("Linked List: ");
while (node != NULL) {
printf("%d -> ", node->data);
node = node->next;
}
printf("NULL\n");
}

// Main function
int main() {
struct Node* head = NULL;
int choice, data;

while (1) {
printf("\n1. Insert\n");
printf("2. Delete\n");
printf("3. Print List\n");
printf("4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch (choice) {
case 1:
printf("Enter data to insert: ");
scanf("%d", &data);
insert(&head, data);
break;
case 2:
printf("Enter data to delete: ");
scanf("%d", &data);
deleteNode(&head, data);
break;
case 3:
printList(head);
break;
case 4:
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}

return 0;
}
Output:
Exercise 3: Linked List Applications
i) Create a program to detect and remove duplicates from a linked list.
Source Code:
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node in the linked list


struct Node {
int data;
struct Node* next;
};
// Function to insert a new node at the beginning of the linked list
void insert(struct Node** head_ref, int new_data) {
// Allocate memory for new node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
// Assign data to new node
new_node->data = new_data;
// Make next of new node as head
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}
// Function to remove duplicates from the linked list
void removeDuplicates(struct Node* head) {
struct Node* current = head;
struct Node* next_unique;

// Traverse the list


while (current != NULL && current->next != NULL) {
struct Node* temp = current;

// Compare current node with all the nodes after it


while (temp->next != NULL) {
if (current->data == temp->next->data) {
next_unique = temp->next->next;
free(temp->next);
temp->next = next_unique;
} else {
temp = temp->next;
}
}
current = current->next;
}
}
// Function to print the linked list
void printList(struct Node* node) {
printf("Linked List: ");
while (node != NULL) {
printf("%d -> ", node->data);
node = node->next;
}
printf("NULL\n");
}

// Main function
int main() {
struct Node* head = NULL;
int data;
// Creating the linked list
while (1) {
printf("Enter data to insert (Enter -1 to stop): ");
scanf("%d", &data);
if (data == -1)
break;
insert(&head, data);
}

// Removing duplicates
removeDuplicates(head);
printf("Duplicates removed.\n");

// Printing the modified linked list


printList(head);

return 0;
}
Output:
ii) Implement a linked list to represent polynomials and perform addition.
Source Code:
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node in the linked list representing a term in a polynomial
struct Node {
int coefficient;
int exponent;
struct Node* next;
};

// Function to insert a new term (node) into the polynomial linked list
void insertTerm(struct Node** head_ref, int coef, int exp) {
// Allocate memory for new node
struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
// Assign coefficient and exponent to new node
new_node->coefficient = coef;
new_node->exponent = exp;
// Make next of new node as head
new_node->next = (*head_ref);
// Move the head to point to the new node
(*head_ref) = new_node;
}

// Function to add two polynomials represented by linked lists


struct Node* addPolynomials(struct Node* poly1, struct Node* poly2) {
struct Node* result = NULL;
struct Node* ptr1 = poly1;
struct Node* ptr2 = poly2;

while (ptr1 != NULL && ptr2 != NULL) {


// If the exponent of current term in poly1 is greater
if (ptr1->exponent > ptr2->exponent) {
insertTerm(&result, ptr1->coefficient, ptr1->exponent);
ptr1 = ptr1->next;
}
// If the exponent of current term in poly2 is greater
else if (ptr1->exponent < ptr2->exponent) {
insertTerm(&result, ptr2->coefficient, ptr2->exponent);
ptr2 = ptr2->next;
}
// If the exponents are equal, add coefficients and insert into result
else {
insertTerm(&result, ptr1->coefficient + ptr2->coefficient, ptr1->exponent);
ptr1 = ptr1->next;
ptr2 = ptr2->next;
}
}

// Copy remaining terms from poly1


while (ptr1 != NULL) {
insertTerm(&result, ptr1->coefficient, ptr1->exponent);
ptr1 = ptr1->next;
}

// Copy remaining terms from poly2


while (ptr2 != NULL) {
insertTerm(&result, ptr2->coefficient, ptr2->exponent);
ptr2 = ptr2->next;
}

return result;
}

// Function to print a polynomial


void printPolynomial(struct Node* poly) {
printf("Polynomial: ");
while (poly != NULL) {
printf("%dx^%d ", poly->coefficient, poly->exponent);
if (poly->next != NULL)
printf("+ ");
poly = poly->next;
}
printf("\n");
}

// Main function
int main() {
struct Node* poly1 = NULL;
struct Node* poly2 = NULL;
struct Node* result = NULL;
int coef, exp;

// Input for polynomial 1


printf("Enter terms for Polynomial 1 (Enter -1 for both coefficient and exponent to
stop):\n");
while (1) {
printf("Enter coefficient: ");
scanf("%d", &coef);
if (coef == -1)
break;
printf("Enter exponent: ");
scanf("%d", &exp);
if (exp == -1)
break;
insertTerm(&poly1, coef, exp);
}

// Input for polynomial 2


printf("Enter terms for Polynomial 2 (Enter -1 for both coefficient and exponent to
stop):\n");
while (1) {
printf("Enter coefficient: ");
scanf("%d", &coef);
if (coef == -1)
break;
printf("Enter exponent: ");
scanf("%d", &exp);
if (exp == -1)
break;
insertTerm(&poly2, coef, exp);
}

// Add the polynomials


result = addPolynomials(poly1, poly2);
// Print the polynomials and their sum
printPolynomial(poly1);
printPolynomial(poly2);
printf("Sum of polynomials:\n");
printPolynomial(result);

return 0;
}
Output:

iii) Implement a double-ended queue (deque) with essential operations.


Source Code:
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

// Structure for deque


struct Deque {
int arr[MAX_SIZE];
int front, rear;
};

// Initialize deque
void initDeque(struct Deque *deque) {
deque->front = -1;
deque->rear = -1;
}

// Check if deque is empty


int isEmpty(struct Deque *deque) {
return (deque->front == -1);
}

// Check if deque is full


int isFull(struct Deque *deque) {
return ((deque->rear + 1) % MAX_SIZE == deque->front);
}

// Insert element at front end of deque


void insertFront(struct Deque *deque, int data) {
if (isFull(deque)) {
printf("Deque is full. Insertion failed.\n");
return;
}
if (isEmpty(deque)) {
deque->front = 0;
deque->rear = 0;
} else {
deque->front = (deque->front - 1 + MAX_SIZE) % MAX_SIZE;
}
deque->arr[deque->front] = data;
}

// Insert element at rear end of deque


void insertRear(struct Deque *deque, int data) {
if (isFull(deque)) {
printf("Deque is full. Insertion failed.\n");
return;
}
if (isEmpty(deque)) {
deque->front = 0;
deque->rear = 0;
} else {
deque->rear = (deque->rear + 1) % MAX_SIZE;
}
deque->arr[deque->rear] = data;
}

// Delete element from front end of deque


void deleteFront(struct Deque *deque) {
if (isEmpty(deque)) {
printf("Deque is empty. Deletion failed.\n");
return;
}
if (deque->front == deque->rear) {
deque->front = -1;
deque->rear = -1;
} else {
deque->front = (deque->front + 1) % MAX_SIZE;
}
}

// Delete element from rear end of deque


void deleteRear(struct Deque *deque) {
if (isEmpty(deque)) {
printf("Deque is empty. Deletion failed.\n");
return;
}
if (deque->front == deque->rear) {
deque->front = -1;
deque->rear = -1;
} else {
deque->rear = (deque->rear - 1 + MAX_SIZE) % MAX_SIZE;
}
}

// Display elements of deque


void display(struct Deque *deque) {
if (isEmpty(deque)) {
printf("Deque is empty.\n");
return;
}
printf("Deque elements: ");
int i = deque->front;
while (i != deque->rear) {
printf("%d ", deque->arr[i]);
i = (i + 1) % MAX_SIZE;
}
printf("%d\n", deque->arr[i]);
}

// Main function
int main() {
struct Deque deque;
initDeque(&deque);

int choice, data;


while (1) {
printf("\n1. Insert element at front\n");
printf("2. Insert element at rear\n");
printf("3. Delete element from front\n");
printf("4. Delete element from rear\n");
printf("5. Display deque\n");
printf("6. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);

switch (choice) {
case 1:
printf("Enter element to insert at front: ");
scanf("%d", &data);
insertFront(&deque, data);
break;
case 2:
printf("Enter element to insert at rear: ");
scanf("%d", &data);
insertRear(&deque, data);
break;
case 3:
deleteFront(&deque);
printf("Element deleted from front.\n");
break;
case 4:
deleteRear(&deque);
printf("Element deleted from rear.\n");
break;
case 5:
display(&deque);
break;
case 6:
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}

return 0;
}
Output:
Exercise 4: Double Linked List Implementation

i) Implement a doubly linked list and perform various operations to understand its
properties and applications.
Source Code:
#include <stdio.h>
#include <stdlib.h>

// Define the structure for a node in the doubly linked list


struct Node {
int data;
struct Node* prev;
struct Node* next;
};

// Function to create a new node


struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
newNode->data = data;
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}

// Function to insert a new node at the beginning of the doubly linked list
void insertAtBeginning(struct Node** head_ref, int data) {
struct Node* newNode = createNode(data);
if (*head_ref == NULL) {
*head_ref = newNode;
} else {
newNode->next = *head_ref;
(*head_ref)->prev = newNode;
*head_ref = newNode;
}
}

// Function to insert a new node at the end of the doubly linked list
void insertAtEnd(struct Node** head_ref, int data) {
struct Node* newNode = createNode(data);
if (*head_ref == NULL) {
*head_ref = newNode;
} else {
struct Node* temp = *head_ref;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
newNode->prev = temp;
}
}

// Function to delete the first occurrence of a node with given data from the doubly linked list
void deleteNode(struct Node** head_ref, int data) {
if (*head_ref == NULL) {
printf("List is empty. Deletion failed.\n");
return;
}
struct Node* temp = *head_ref;
// If the node to be deleted is the first node
if (temp->data == data) {
*head_ref = temp->next;
if (*head_ref != NULL) {
(*head_ref)->prev = NULL;
}
free(temp);
printf("Node with data %d deleted.\n", data);
return;
}
// Search for the node to be deleted
while (temp != NULL && temp->data != data) {
temp = temp->next;
}
if (temp == NULL) {
printf("Node with data %d not found.\n", data);
return;
}
temp->prev->next = temp->next;
if (temp->next != NULL) {
temp->next->prev = temp->prev;
}
free(temp);
printf("Node with data %d deleted.\n", data);
}
// Function to display the doubly linked list
void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}
printf("Doubly Linked List: ");
while (head != NULL) {
printf("%d ", head->data);
head = head->next;
}
printf("\n");
}

// Main function
int main() {
struct Node* head = NULL;
int choice, data;

while (1) {
printf("\n1. Insert at beginning\n");
printf("2. Insert at end\n");
printf("3. Delete node\n");
printf("4. Display\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter data to insert at beginning: ");
scanf("%d", &data);
insertAtBeginning(&head, data);
break;
case 2:
printf("Enter data to insert at end: ");
scanf("%d", &data);
insertAtEnd(&head, data);
break;
case 3:
printf("Enter data to delete: ");
scanf("%d", &data);
deleteNode(&head, data);
break;
case 4:
display(head);
break;
case 5:
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}

return 0;
}
Output:

ii) Implement a circular linked list and perform insertion, deletion, and traversal.
Source code:
#include <stdio.h>
#include <stdlib.h>
// Define the structure for a node in the circular linked list
struct Node {
int data;
struct Node* next;
};
// Function to create a new node
struct Node* createNode(int data) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
newNode->data = data;
newNode->next = NULL;
return newNode;
}
// Function to insert a new node at the beginning of the circular linked list
void insertAtBeginning(struct Node** head_ref, int data) {
struct Node* newNode = createNode(data);
if (*head_ref == NULL) {
*head_ref = newNode;
newNode->next = newNode;
} else {
struct Node* last = *head_ref;
while (last->next != *head_ref) {
last = last->next;
}
newNode->next = *head_ref;
last->next = newNode;
*head_ref = newNode;
}
}
// Function to insert a new node at the end of the circular linked list
void insertAtEnd(struct Node** head_ref, int data) {
struct Node* newNode = createNode(data);
if (*head_ref == NULL) {
*head_ref = newNode;
newNode->next = newNode;
} else {
struct Node* last = *head_ref;
while (last->next != *head_ref) {
last = last->next;
}
last->next = newNode;
newNode->next = *head_ref;
}
}
// Function to delete the first occurrence of a node with given data from the circular linked
list
void deleteNode(struct Node** head_ref, int data) {
if (*head_ref == NULL) {
printf("List is empty. Deletion failed.\n");
return;
}
struct Node *temp = *head_ref, *prev;
if (temp->data == data) {
if (temp->next == temp) {
free(temp);
*head_ref = NULL;
} else {
while (temp->next != *head_ref) {
temp = temp->next;
}
temp->next = (*head_ref)->next;
temp = *head_ref;
*head_ref = (*head_ref)->next;
free(temp);
}
printf("Node with data %d deleted.\n", data);
return;
}
while (temp->next != *head_ref && temp->data != data) {
prev = temp;
temp = temp->next;
}
if (temp->data != data) {
printf("Node with data %d not found.\n", data);
return;
}
prev->next = temp->next;
free(temp);
printf("Node with data %d deleted.\n", data);
}
// Function to display the circular linked list
void display(struct Node* head) {
if (head == NULL) {
printf("List is empty.\n");
return;
}
struct Node* temp = head;
do {
printf("%d ", temp->data);
temp = temp->next;
} while (temp != head);
printf("\n");
}
// Main function
int main() {
struct Node* head = NULL;
int choice, data;

while (1) {
printf("\n1. Insert at beginning\n");
printf("2. Insert at end\n");
printf("3. Delete node\n");
printf("4. Display\n");
printf("5. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter data to insert at beginning: ");
scanf("%d", &data);
insertAtBeginning(&head, data);
break;
case 2:
printf("Enter data to insert at end: ");
scanf("%d", &data);
insertAtEnd(&head, data);
break;
case 3:
printf("Enter data to delete: ");
scanf("%d", &data);
deleteNode(&head, data);
break;
case 4:
display(head);
break;
case 5:
printf("Exiting...\n");
exit(0);
default:
printf("Invalid choice!\n");
}
}

return 0;
}

Output:
EXERCISE 5:
1) IMPLEMENT A STACK USING ARRAYS AND LINKED LISTS?
1)Stack using Arrays:

SOURCE CODE:
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef struct {
int items[MAX_SIZE];
int top;
} StackArray;

void initStack(StackArray *stack) {


stack->top = -1;
}

int isFull(StackArray *stack) {


return stack->top == MAX_SIZE - 1;
}

int isEmpty(StackArray *stack) {


return stack->top == -1;
}

void push(StackArray *stack, int item) {


if (isFull(stack)) {
printf("Stack overflow!\n");
return;
}
stack->items[++stack->top] = item;
}

int pop(StackArray *stack) {


if (isEmpty(stack)) {
printf("Stack underflow!\n");
return -1;
}
return stack->items[stack->top--];
}

int peek(StackArray *stack) {


if (isEmpty(stack)) {
printf("Stack is empty!\n");
return -1;
}
return stack->items[stack->top];
}

int main() {
StackArray stack;
initStack(&stack);

push(&stack, 1);
push(&stack, 2);
push(&stack, 3);

printf("Top of the stack: %d\n", peek(&stack)); // Output: 3

printf("Popping elements:\n");
while (!isEmpty(&stack)) {
printf("%d\n", pop(&stack));
}

return 0;
}

OUTPUT:

2)Stack using Linked List:

SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {


int data;
struct Node *next;
} Node;

typedef struct {
Node *top;
} StackLinkedList;
void initStack(StackLinkedList *stack) {
stack->top = NULL;
}

int isEmpty(StackLinkedList *stack) {


return stack->top == NULL;
}

void push(StackLinkedList *stack, int item) {


Node *newNode = (Node *)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation failed!\n");
return;
}
newNode->data = item;
newNode->next = stack->top;
stack->top = newNode;
}

int pop(StackLinkedList *stack) {


if (isEmpty(stack)) {
printf("Stack underflow!\n");
return -1;
}
int item = stack->top->data;
Node *temp = stack->top;
stack->top = stack->top->next;
free(temp);
return item;
}

int peek(StackLinkedList *stack) {


if (isEmpty(stack)) {
printf("Stack is empty!\n");
return -1;
}
return stack->top->data;
}

int main() {
StackLinkedList stack;
initStack(&stack);

push(&stack, 1);
push(&stack, 2);
push(&stack, 3);

printf("Top of the stack: %d\n", peek(&stack)); // Output: 3

printf("Popping elements:\n");
while (!isEmpty(&stack)) {
printf("%d\n", pop(&stack));
}

return 0;
}
output:

2) WRITE A PROGRAM TO EVALUATE POSTFIX EXPRESSION USING A


STACK ?
SOURCE CODE:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_SIZE 100

typedef struct {
int items[MAX_SIZE];
int top;
} Stack;

void initStack(Stack *stack) {


stack->top = -1;
}

int isFull(Stack *stack) {


return stack->top == MAX_SIZE - 1;
}

int isEmpty(Stack *stack) {


return stack->top == -1;
}

void push(Stack *stack, int item) {


if (isFull(stack)) {
printf("Stack overflow!\n");
exit(EXIT_FAILURE);
}
stack->items[++stack->top] = item;
}
int pop(Stack *stack) {
if (isEmpty(stack)) {
printf("Stack underflow!\n");
exit(EXIT_FAILURE);
}
return stack->items[stack->top--];
}

int evaluatePostfix(char *expression) {


Stack stack;
initStack(&stack);

while (*expression) {
if (isdigit(*expression)) {
push(&stack, *expression - '0');
} else {
int operand2 = pop(&stack);
int operand1 = pop(&stack);
switch (*expression) {
case '+':
push(&stack, operand1 + operand2);
break;
case '-':
push(&stack, operand1 - operand2);
break;
case '*':
push(&stack, operand1 * operand2);
break;
case '/':
push(&stack, operand1 / operand2);
break;
default:
printf("Invalid operator: %c\n", *expression);
exit(EXIT_FAILURE);
}
}
expression++;
}
return pop(&stack);
}

int main() {
char expression[] = "532*+"; // Postfix expression: 5 + (3 * 2)
int result = evaluatePostfix(expression);
printf("Result: %d\n", result); // Output: 11
return 0;
}

OUTPUT :

3)IMPLEMENT A PROGRAM TO CHECK FOR BALANCED


PARENTHESES USING A STACK?
SOURCE CODE:
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 100

typedef struct {
char items[MAX_SIZE];
int top;
} Stack;

void initStack(Stack *stack) {


stack->top = -1;
}

int isFull(Stack *stack) {


return stack->top == MAX_SIZE - 1;
}

int isEmpty(Stack *stack) {


return stack->top == -1;
}

void push(Stack *stack, char item) {


if (isFull(stack)) {
printf("Stack overflow!\n");
exit(EXIT_FAILURE);
}
stack->items[++stack->top] = item;
}

char pop(Stack *stack) {


if (isEmpty(stack)) {
printf("Stack underflow!\n");
exit(EXIT_FAILURE);
}
return stack->items[stack->top--];
}

int isBalanced(char *expression) {


Stack stack;
initStack(&stack);

while (*expression) {
if (*expression == '(') {
push(&stack, *expression);
} else if (*expression == ')') {
if (isEmpty(&stack) || pop(&stack) != '(') {
return 0; // Unbalanced
}
}
expression++;
}

// Check if stack is empty after processing all parentheses


return isEmpty(&stack);
}

int main() {
char expression[] = "((()))()"; // Balanced parentheses
if (isBalanced(expression)) {
printf("Parentheses are balanced.\n");
} else {
printf("Parentheses are not balanced.\n");
}

return 0;
}
OUTPUT:
EXERCISE 6: QUEUE OPERATION
I) IMPLEMENT A QUEUE USING ARRAYS AND LINKED LISTS ?
1)Queue using Arrays:
SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

typedef struct {
int items[MAX_SIZE];
int front, rear;
} QueueArray;

void initQueue(QueueArray *queue) {


queue->front = -1;
queue->rear = -1;
}

int isFull(QueueArray *queue) {


return (queue->rear == MAX_SIZE - 1);
}

int isEmpty(QueueArray *queue) {


return (queue->front == -1 || queue->front > queue->rear);
}

void enqueue(QueueArray *queue, int item) {


if (isFull(queue)) {
printf("Queue overflow!\n");
return;
}
if (queue->front == -1) {
queue->front = 0;
}
queue->rear++;
queue->items[queue->rear] = item;
}
int dequeue(QueueArray *queue) {
if (isEmpty(queue)) {
printf("Queue underflow!\n");
return -1;
}
int item = queue->items[queue->front];
queue->front++;
return item;
}
int main() {
QueueArray queue;
initQueue(&queue);

enqueue(&queue, 1);
enqueue(&queue, 2);
enqueue(&queue, 3);

printf("Dequeued item: %d\n", dequeue(&queue)); // Output: 1


printf("Dequeued item: %d\n", dequeue(&queue)); // Output: 2
printf("Dequeued item: %d\n", dequeue(&queue)); // Output: 3
printf("Dequeued item: %d\n", dequeue(&queue)); // Output: Queue underflow!
return 0;
}
OUTPUT:

2) Queue using Linked List:


SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {


int data;
struct Node *next;
} Node;

typedef struct {
Node *front, *rear;
} QueueLinkedList;

void initQueue(QueueLinkedList *queue) {


queue->front = queue->rear = NULL;
}

int isEmpty(QueueLinkedList *queue) {


return queue->front == NULL;
}

void enqueue(QueueLinkedList *queue, int item) {


Node *newNode = (Node *)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Memory allocation failed!\n");
return;
}
newNode->data = item;
newNode->next = NULL;
if (isEmpty(queue)) {
queue->front = queue->rear = newNode;
} else {
queue->rear->next = newNode;
queue->rear = newNode;
}
}

int dequeue(QueueLinkedList *queue) {


if (isEmpty(queue)) {
printf("Queue underflow!\n");
return -1;
}
int item = queue->front->data;
Node *temp = queue->front;
queue->front = queue->front->next;
if (queue->front == NULL) {
queue->rear = NULL;
}
free(temp);
return item;
}

int main() {
QueueLinkedList queue;
initQueue(&queue);

enqueue(&queue, 1);
enqueue(&queue, 2);
enqueue(&queue, 3);

printf("Dequeued item: %d\n", dequeue(&queue)); // Output: 1


printf("Dequeued item: %d\n", dequeue(&queue)); // Output: 2
printf("Dequeued item: %d\n", dequeue(&queue)); // Output: 3
printf("Dequeued item: %d\n", dequeue(&queue)); // Output: Queue underflow!

return 0;
}

OUTPUT:
2)DEVELOP A PROGRAM TO SIMULATE A SIMPLE PRINTER QUEUE SYSTEM?
SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h> // for sleep()

#define MAX_QUEUE_SIZE 100

typedef struct {
int jobNumber;
} PrintJob;

typedef struct {
PrintJob items[MAX_QUEUE_SIZE];
int front, rear;
} PrinterQueue;

void initQueue(PrinterQueue *queue) {


queue->front = -1;
queue->rear = -1;
}

bool isFull(PrinterQueue *queue) {


return (queue->rear == MAX_QUEUE_SIZE - 1);
}

bool isEmpty(PrinterQueue *queue) {


return (queue->front == -1 || queue->front > queue->rear);
}
void enqueue(PrinterQueue *queue, PrintJob job) {
if (isFull(queue)) {
printf("Printer queue is full. Cannot add more jobs.\n");
return;
}
if (queue->front == -1) {
queue->front = 0;
}
queue->rear++;
queue->items[queue->rear] = job;
printf("Job %d added to the printer queue.\n", job.jobNumber);
}

PrintJob dequeue(PrinterQueue *queue) {


PrintJob job;
if (isEmpty(queue)) {
printf("Printer queue is empty. No jobs to print.\n");
job.jobNumber = -1;
return job;
}
job = queue->items[queue->front];
queue->front++;
if (queue->front > queue->rear) {
queue->front = queue->rear = -1;
}
return job;
}

void printJob(PrintJob job) {


printf("Printing job %d...\n", job.jobNumber);
sleep(1); // Simulating printing time
printf("Job %d printed successfully.\n", job.jobNumber);
}

int main() {
PrinterQueue printerQueue;
initQueue(&printerQueue);

// Simulating adding print jobs


PrintJob job1 = {1};
PrintJob job2 = {2};
PrintJob job3 = {3};
enqueue(&printerQueue, job1);
enqueue(&printerQueue, job2);
enqueue(&printerQueue, job3);

printf("\nPrinting started...\n");
// Simulating printing
while (!isEmpty(&printerQueue)) {
PrintJob job = dequeue(&printerQueue);
if (job.jobNumber != -1) {
printJob(job);
}
}
printf("All jobs printed.\n");

return 0;
}
OUTPUT:

3)SOLVE PROBLEMS INVOLVING CIRCULAR QUEUES?


EXERCISE 7:STACK AND QUEUE APPLICATIONS
1) USE A STACK TO EVALUATE AN INFIX EXPRESSION AND CONVERT IT TO POSTFIX?
SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

#define MAX_SIZE 100

// Structure to represent a stack


typedef struct {
int top;
char items[MAX_SIZE];
} Stack;

// Function to initialize the stack


void initialize(Stack *stack) {
stack->top = -1;
}

// Function to check if the stack is full


int isFull(Stack *stack) {
return stack->top == MAX_SIZE - 1;
}

// Function to check if the stack is empty


int isEmpty(Stack *stack) {
return stack->top == -1;
}
// Function to push an element onto the stack
void push(Stack *stack, char c) {
if (isFull(stack)) {
printf("Stack overflow\n");
exit(EXIT_FAILURE);
}
stack->items[++stack->top] = c;
}

// Function to pop an element from the stack


char pop(Stack *stack) {
if (isEmpty(stack)) {
printf("Stack underflow\n");
exit(EXIT_FAILURE);
}
return stack->items[stack->top--];
}

// Function to get the precedence of an operator


int precedence(char op) {
switch (op) {
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
default:
return 0;
}
}

// Function to convert infix expression to postfix


void infixToPostfix(char *infix, char *postfix) {
Stack stack;
initialize(&stack);
int i = 0, j = 0;

while (infix[i] != '\0') {


char ch = infix[i];
if (isdigit(ch)) {
postfix[j++] = ch;
} else if (ch == '(') {
push(&stack, ch);
} else if (ch == ')') {
while (!isEmpty(&stack) && stack.items[stack.top] != '(') {
postfix[j++] = pop(&stack);
}
if (!isEmpty(&stack) && stack.items[stack.top] == '(') {
pop(&stack); // Discard '('
} else {
printf("Invalid expression\n");
exit(EXIT_FAILURE);
}
} else {
while (!isEmpty(&stack) && precedence(ch) <= precedence(stack.items[stack.top]))
{
postfix[j++] = pop(&stack);
}
push(&stack, ch);
}
i++;
}

while (!isEmpty(&stack)) {
if (stack.items[stack.top] == '(') {
printf("Invalid expression\n");
exit(EXIT_FAILURE);
}
postfix[j++] = pop(&stack);
}

postfix[j] = '\0';
}

// Function to evaluate postfix expression


int evaluatePostfix(char *postfix) {
Stack stack;
initialize(&stack);
int i = 0;

while (postfix[i] != '\0') {


char ch = postfix[i];
if (isdigit(ch)) {
push(&stack, ch - '0'); // Convert character to integer
} else {
int operand2 = pop(&stack);
int operand1 = pop(&stack);
switch (ch) {
case '+':
push(&stack, operand1 + operand2);
break;
case '-':
push(&stack, operand1 - operand2);
break;
case '*':
push(&stack, operand1 * operand2);
break;
case '/':
push(&stack, operand1 / operand2);
break;
}
}
i++;
}

return pop(&stack);
}

int main() {
char infix[MAX_SIZE], postfix[MAX_SIZE];

printf("Enter infix expression: ");


scanf("%s", infix);

infixToPostfix(infix, postfix);

printf("Postfix expression: %s\n", postfix);

int result = evaluatePostfix(postfix);


printf("Result of evaluation: %d\n", result);
return 0;
}

OUTPUT:

2)CREATE A PROGRAM TO DETERMINE WHETHER A GIVEN STRING IS A PALINDROME OR NOT?


SOURCE CODE:

#include <stdio.h>
#include <string.h>
#include <ctype.h>

// Function to check if a character is alphanumeric


int isAlphanumeric(char ch) {
return isalpha(ch) || isdigit(ch);
}

// Function to convert a character to lowercase


char toLower(char ch) {
if (isupper(ch)) {
return tolower(ch);
}
return ch;
}

// Function to check if a string is a palindrome


int isPalindrome(char *str) {
int left = 0;
int right = strlen(str) - 1;

while (left < right) {


while (left < right && !isAlphanumeric(str[left])) {
left++;
}
while (left < right && !isAlphanumeric(str[right])) {
right--;
}
if (toLower(str[left]) != toLower(str[right])) {
return 0; // Not a palindrome
}
left++;
right--;
}
return 1; // Palindrome
}

int main() {
char str[100];

printf("Enter a string: ");


fgets(str, sizeof(str), stdin);
str[strcspn(str, "\n")] = '\0'; // Remove trailing newline if present

if (isPalindrome(str)) {
printf("'%s' is a palindrome.\n", str);
} else {
printf("'%s' is not a palindrome.\n", str);
}

return 0;
}
OUTPUT:

3)IMPLEMENT A STACK OR QUEUE TO PERFORM COMPARISION AND CHECK FOR SYMMETRY?


EXERCISE 8: BINARY SEARCH TREE
1)IMPLEMENT A BST USING LINKEDLIST?
SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>

// Define a structure for a BST node


typedef struct TreeNode {
int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;

// Function to create a new BST node


TreeNode *createNode(int data) {
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
if (newNode == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}

// Function to insert a node into the BST


TreeNode *insert(TreeNode *root, int data) {
if (root == NULL) {
return createNode(data);
}
if (data < root->data) {
root->left = insert(root->left, data);
} else if (data > root->data) {
root->right = insert(root->right, data);
}
return root;
}

// Function to search for a key in the BST


TreeNode *search(TreeNode *root, int key) {
if (root == NULL || root->data == key) {
return root;
}
if (key < root->data) {
return search(root->left, key);
}
return search(root->right, key);
}

// Function to perform inorder traversal of the BST


void inorder(TreeNode *root) {
if (root != NULL) {
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}

int main() {
TreeNode *root = NULL;

// Insert nodes into the BST


root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);

// Print the inorder traversal of the BST


printf("Inorder traversal of the BST: ");
inorder(root);
printf("\n");

// Search for a key in the BST


int key = 40;
TreeNode *result = search(root, key);
if (result != NULL) {
printf("%d found in the BST.\n", key);
} else {
printf("%d not found in the BST.\n", key);
}

return 0;
}
OUTPUT:

2)TRAVERSING OF BST?
SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>

// Define a structure for a BST node


typedef struct TreeNode {
int data;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;

// Function to create a new BST node


TreeNode *createNode(int data) {
TreeNode *newNode = (TreeNode *)malloc(sizeof(TreeNode));
if (newNode == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
newNode->data = data;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}

// Function to insert a node into the BST


TreeNode *insert(TreeNode *root, int data) {
if (root == NULL) {
return createNode(data);
}
if (data < root->data) {
root->left = insert(root->left, data);
} else if (data > root->data) {
root->right = insert(root->right, data);
}
return root;
}

// Inorder traversal: Left -> Root -> Right


void inorder(TreeNode *root) {
if (root != NULL) {
inorder(root->left);
printf("%d ", root->data);
inorder(root->right);
}
}

// Preorder traversal: Root -> Left -> Right


void preorder(TreeNode *root) {
if (root != NULL) {
printf("%d ", root->data);
preorder(root->left);
preorder(root->right);
}
}

// Postorder traversal: Left -> Right -> Root


void postorder(TreeNode *root) {
if (root != NULL) {
postorder(root->left);
postorder(root->right);
printf("%d ", root->data);
}
}

int main() {
TreeNode *root = NULL;

// Insert nodes into the BST


root = insert(root, 50);
insert(root, 30);
insert(root, 20);
insert(root, 40);
insert(root, 70);
insert(root, 60);
insert(root, 80);

// Inorder traversal
printf("Inorder traversal of the BST: ");
inorder(root);
printf("\n");

// Preorder traversal
printf("Preorder traversal of the BST: ");
preorder(root);
printf("\n");

// Postorder traversal
printf("Postorder traversal of the BST: ");
postorder(root);
printf("\n");

return 0;
}
OUTPUT:
EXERCISE 9:HASHING
1)IMPLEMENT A HASH TABLE WITH COLLISION RESOLUTION TECHNIQUES?
SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define TABLE_SIZE 10

// Define a structure for each node in the linked list


typedef struct Node {
char key[50];
int value;
struct Node *next;
} Node;

// Define a structure for the hash table


typedef struct {
Node *buckets[TABLE_SIZE];
} HashTable;

// Hash function to calculate the index for a given key


int hash(char *key) {
int hashValue = 0;
for (int i = 0; key[i] != '\0'; i++) {
hashValue = (hashValue << 5) + key[i];
}
return hashValue % TABLE_SIZE;
}
// Function to create a new node
Node *createNode(char *key, int value) {
Node *newNode = (Node *)malloc(sizeof(Node));
if (newNode == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
strcpy(newNode->key, key);
newNode->value = value;
newNode->next = NULL;
return newNode;
}

// Function to insert a key-value pair into the hash table


void insert(HashTable *hashTable, char *key, int value) {
int index = hash(key);
Node *newNode = createNode(key, value);
if (hashTable->buckets[index] == NULL) {
hashTable->buckets[index] = newNode;
} else {
Node *temp = hashTable->buckets[index];
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newNode;
}
}

// Function to search for a key in the hash table and return its value
int search(HashTable *hashTable, char *key) {
int index = hash(key);
Node *temp = hashTable->buckets[index];
while (temp != NULL) {
if (strcmp(temp->key, key) == 0) {
return temp->value;
}
temp = temp->next;
}
return -1; // Key not found
}

// Function to display the hash table


void display(HashTable *hashTable) {
printf("Hash Table:\n");
for (int i = 0; i < TABLE_SIZE; i++) {
printf("Bucket %d:", i);
Node *temp = hashTable->buckets[i];
while (temp != NULL) {
printf(" -> %s:%d", temp->key, temp->value);
temp = temp->next;
}
printf("\n");
}
}

// Function to delete the hash table


void deleteHashTable(HashTable *hashTable) {
for (int i = 0; i < TABLE_SIZE; i++) {
Node *current = hashTable->buckets[i];
while (current != NULL) {
Node *temp = current;
current = current->next;
free(temp);
}
hashTable->buckets[i] = NULL;
}
}

int main() {
HashTable hashTable;
for (int i = 0; i < TABLE_SIZE; i++) {
hashTable.buckets[i] = NULL;
}

// Insert key-value pairs into the hash table


insert(&hashTable, "John", 25);
insert(&hashTable, "Jane", 30);
insert(&hashTable, "Alice", 35);
insert(&hashTable, "Bob", 40);

// Display the hash table


display(&hashTable);

// Search for a key and display its value


printf("Value for key 'Alice': %d\n", search(&hashTable, "Alice"));
printf("Value for key 'Mark': %d\n", search(&hashTable, "Mark"));

// Delete the hash table


deleteHashTable(&hashTable);
return 0;
}
OUTPUT:

2)WRITE A PROGRAM TO IMPLEMENT A SIMPLE CACHE USING HASHING?


SOURCE CODE:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define CACHE_SIZE 10
#define TABLE_SIZE 20

// Define a structure for cache entry


typedef struct {
char key[50];
int value;
} CacheEntry;
// Define a structure for the hash table
typedef struct {
CacheEntry *buckets[TABLE_SIZE];
} HashTable;

// Hash function to calculate the index for a given key


int hash(char *key) {
int hashValue = 0;
for (int i = 0; key[i] != '\0'; i++) {
hashValue = (hashValue << 5) + key[i];
}
return hashValue % TABLE_SIZE;
}

// Function to create a new cache entry


CacheEntry *createCacheEntry(char *key, int value) {
CacheEntry *newEntry = (CacheEntry *)malloc(sizeof(CacheEntry));
if (newEntry == NULL) {
perror("Memory allocation failed");
exit(EXIT_FAILURE);
}
strcpy(newEntry->key, key);
newEntry->value = value;
return newEntry;
}

// Function to initialize the hash table


void initHashTable(HashTable *hashTable) {
for (int i = 0; i < TABLE_SIZE; i++) {
hashTable->buckets[i] = NULL;
}
}

// Function to insert a key-value pair into the hash table (cache)


void insert(HashTable *hashTable, char *key, int value) {
int index = hash(key);
CacheEntry *newEntry = createCacheEntry(key, value);
hashTable->buckets[index] = newEntry;
}

// Function to search for a key in the hash table (cache)


int search(HashTable *hashTable, char *key) {
int index = hash(key);
if (hashTable->buckets[index] != NULL && strcmp(hashTable->buckets[index]->key,
key) == 0) {
return hashTable->buckets[index]->value;
}
return -1; // Key not found in cache
}

int main() {
HashTable hashTable;
initHashTable(&hashTable);

// Insert key-value pairs into the cache


insert(&hashTable, "John", 25);
insert(&hashTable, "Jane", 30);
insert(&hashTable, "Alice", 35);
insert(&hashTable, "Bob", 40);

// Access values from cache


printf("Value for key 'Alice': %d\n", search(&hashTable, "Alice"));
printf("Value for key 'Mark': %d\n", search(&hashTable, "Mark"));

return 0;
}
OUTPUT:

You might also like