0% found this document useful (0 votes)
41 views72 pages

Data Structures Lab Experiments 2023

The document outlines the Data Structure Lab experiments for the 3rd semester at Bundelkhand Institute of Engineering and Technology, Jhansi, for the session 2023-2024. It includes objectives, codes, and outputs for various sorting techniques (Bubble Sort, Insertion Sort, Selection Sort, Shell Sort, Radix Sort, Quick Sort) and searching techniques (Linear Search, Binary Search) along with hashing methods. Each experiment is documented with specific dates and signatures, showcasing the practical implementation of data structures.
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)
41 views72 pages

Data Structures Lab Experiments 2023

The document outlines the Data Structure Lab experiments for the 3rd semester at Bundelkhand Institute of Engineering and Technology, Jhansi, for the session 2023-2024. It includes objectives, codes, and outputs for various sorting techniques (Bubble Sort, Insertion Sort, Selection Sort, Shell Sort, Radix Sort, Quick Sort) and searching techniques (Linear Search, Binary Search) along with hashing methods. Each experiment is documented with specific dates and signatures, showcasing the practical implementation of data structures.
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

BUNDELKHAND INSTITUTE OF

ENGINEERING AND TECHNOLOGY


JHANSI

SESSION: 2023-2024

NAME:- SOURAV SHARMA

BRANCH:- COMPUTER SCIENCE AND


ENGINEERING

SUBJECT:- DATA STRUCTURE LAB

SEMESTER:- 3rd

ROLL NUMBER:- 2200430100054


INDEX

[Link]. TITLE DATE SIGN.

01. EXPERIMENT:-01 19/08/23

02. EXPERIMENT:-02 26/08/23

03. EXPERIMENT:-03 02/08/23

04. EXPERIMENT:-04 16/09/23

05. EXPERIMENT:-05 23/09/23

06. EXPERIMENT:-06 30/09/23

07. EXPERIMENT:-07 07/09/23

08. EXPERIMENT:-08 28/10/23

09. EXPERIMENT:-09 04/11/23

10. EXPERIMENT:-10 04/11/23


EXPERIMENT:-01

OBJECTIVE:-

Implementing Sorting Techniques: Bubble Sort, Insertion Sort, Selection Sort, Shell , Sort, Radix
Sort, Quick sort

CODE:-

For all the sorting methods we are going to take the same set of numbers except some.
17,5,9,12,3,7,22,8,19,14

BUBBLE SORTING:-
#include <stdio.h>

void swap(int *xp, int *yp) {


int temp = *xp;
*xp = *yp;
*yp = temp;
}

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], &arr[j+1]);
}

void printArray(int arr[], int size) {


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

int main() {
int arr[] = {17, 5, 9, 12, 3, 7, 22, 8, 19, 14};
int n = sizeof(arr)/sizeof(arr[0]);

printf("Original array: \n");


printArray(arr, n);

bubbleSort(arr, n);

printf("Sorted array: \n");


printArray(arr, n);

return 0;}

1
OUTPUT:-

INSERTION SORT:-

#include <stdio.h>

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


int i, key, j;
for (i = 1; i < n; i++) {
key = arr[i];
j = i - 1;

/* Move elements of arr[0..i-1] that are greater than key to one


position ahead of their current position */
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j = j - 1;
}
arr[j + 1] = key;
}
}

void printArray(int arr[], int size) {


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

int main() {
int arr[] = {17, 5, 9, 12, 3, 7, 22, 8, 19, 14};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: \n");


printArray(arr, n);

insertionSort(arr, n);

printf("Sorted array: \n");


printArray(arr, n);
return 0;}
OUTPUT:-

2
SELECTION SORT:-
#include <stdio.h>

void swap(int *xp, int *yp) {


int temp = *xp;
*xp = *yp;
*yp = temp;
}

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


int i, j, min_idx;

// One by one move the boundary of the unsorted subarray


for (i = 0; i < n-1; i++) {
// Find the minimum element in the unsorted array
min_idx = i;
for (j = i+1; j < n; j++)
if (arr[j] < arr[min_idx])
min_idx = j;

// Swap the found minimum element with the first element


swap(&arr[min_idx], &arr[i]);
}
}

void printArray(int arr[], int size) {


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

int main() {
int arr[] = {17, 5, 9, 12, 3, 7, 22, 8, 19, 14};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: \n");


printArray(arr, n);
selectionSort(arr, n);
printf("Sorted array: \n");
printArray(arr, n);

return 0;
}
OUTPUT:-

3
SHELL SORT:-
#include <stdio.h>

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


for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int temp = arr[i];
int j;
for (j = i; j >= gap && arr[j - gap] > temp; j -= gap)
arr[j] = arr[j - gap];
arr[j] = temp;
}
}
}

void printArray(int arr[], int size) {


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

int main() {
int arr[] = {17, 5, 9, 12, 3, 7, 22, 8, 19, 14};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: \n");


printArray(arr, n);

shellSort(arr, n);

printf("Sorted array using Shell sort: \n");


printArray(arr, n);
return 0;}
OUTPUT:-

RADIX SORT:-
#include <stdio.h>

// Function to find the maximum number in the array


int getMax(int arr[], int n) {
int max = arr[0];
for (int i = 1; i < n; i++)

4
if (arr[i] > max)
max = arr[i];
return max;
}

// Using counting sort to sort the elements based on significant places


void countingSort(int arr[], int n, int exp) {
const int MAX = 10; // Assuming decimal numbers (0-9)
int output[n];
int count[MAX];

// Initialize count array to zero


for (int i = 0; i < MAX; i++)
count[i] = 0;

// Store count of occurrences in count[]


for (int i = 0; i < n; i++)
count[(arr[i] / exp) % 10]++;

// Change count[i] so that count[i] contains actual position of this


digit in output[]
for (int i = 1; i < MAX; i++)
count[i] += count[i - 1];

// Build the output array


for (int i = n - 1; i >= 0; i--) {
output[count[(arr[i] / exp) % 10] - 1] = arr[i];
count[(arr[i] / exp) % 10]--;
}

// Copy the output array to arr[], so that arr[] now contains sorted
numbers according to the current digit
for (int i = 0; i < n; i++)
arr[i] = output[i];
}

// Radix sort function


void radixSort(int arr[], int n) {
// Find the maximum number to determine the number of digits
int max = getMax(arr, n);

// Do counting sort for every digit


for (int exp = 1; max / exp > 0; exp *= 10)
countingSort(arr, n, exp);
}

// Print an array
void printArray(int arr[], int n) {

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

// Main function
int main() {
int arr[] = {17, 5, 9, 12, 3, 7, 22, 8, 19, 14};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: \n");


printArray(arr, n);

radixSort(arr, n);

printf("Sorted array using Radix sort: \n");


printArray(arr, n);

return 0;
}
OUTPUT:-

QUICK SORT :-

#include <stdio.h>

// Function to partition the array and return the pivot index


int partition(int arr[], int low, int high) {
int pivot = arr[high]; // Choose the rightmost element as the pivot
int i = low - 1; // Index of smaller element

for (int j = low; j < high; j++) {


if (arr[j] <= pivot) {
i++;
// Swap arr[i] and arr[j]
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}

// Swap arr[i+1] and arr[high] (pivot)


int temp = arr[i + 1];

6
arr[i + 1] = arr[high];
arr[high] = temp;

return i + 1;
}

// Function to perform Quick Sort


void quickSort(int arr[], int low, int high) {
if (low < high) {
// Find the pivot index such that elements smaller than the
pivot are on the left
// and elements greater than the pivot are on the right
int pivotIndex = partition(arr, low, high);

// Recursively sort the sub-arrays


quickSort(arr, low, pivotIndex - 1);
quickSort(arr, pivotIndex + 1, high);
}
}

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

// Main function
int main() {
int arr[] = {17, 5, 9, 12, 3, 7, 22, 8, 19, 14};
int n = sizeof(arr) / sizeof(arr[0]);

printf("Original array: \n");


printArray(arr, n);

// Perform Quick Sort


quickSort(arr, 0, n - 1);

printf("Sorted array using Quick sort: \n");


printArray(arr, n);

return 0;
}
OUTPUT:-

7
EXPERIMENT:-02

OBJECTIVE:-

Implementing Searching and Hashing Techniques: Linear search, Binary search, Methods for
Hashing: Modulo Division, Digit Extraction, Fold shift, Fold Boundary, Linear Probe for Collision
Resolution. Direct and Subtraction hashing

CODE:-

For the code we are using the same set of numbers for all the searching techniques.
10,25,7,42,15,31,19,5,28,12
Where we will be searching for 15’s index.
LINEAR SEARCH:-
#include <stdio.h>

// Linear search function


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

int main() {
int arr[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(arr) / sizeof(arr[0]);

int key = 15; // Key to search for

printf("Original array: \n");


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

int result = linearSearch(arr, n, key);

if (result != -1) {
printf("Element %d found at index %d.\n", key, result);
} else {
printf("Element %d not found in the array.\n", key);
}
return 0;}

8
OUTPUT:-

BINARY SEARCH:-
#include <stdio.h>

// Binary search function (assumes the array is sorted)


int binarySearch(int arr[], int low, int high, int key) {
while (low <= high) {
int mid = low + (high - low) / 2;

if (arr[mid] == key) {
return mid; // Return the index if the key is found
}

if (arr[mid] < key) {


low = mid + 1;
} else {
high = mid - 1;
}
}

return -1; // Return -1 if the key is not found


}

int main() {
int arr[] = {5, 7, 10, 12, 15, 19, 25, 28, 31, 42};
int n = sizeof(arr) / sizeof(arr[0]);

int key = 15; // Key to search for

printf("Original array: \n");


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

int result = binarySearch(arr, 0, n - 1, key);

if (result != -1) {
printf("Element %d found at index %d.\n", key, result);
} else {
printf("Element %d not found in the array.\n", key);
}

9
return 0;
}
OUTPUT:-

METHODS FOR HASHING:-


MODULO DIVISION:-
#include <stdio.h>

#define SIZE 10 // Size of the hash table

// Hash function using Modulo Division


int hashFunction(int key, int size) {
return key % size;
}

// Insert function for linear probing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to handle collisions


while (hashTable[index] != -1) {
index = (index + 1) % size;
}

hashTable[index] = key;
}

// Search function for linear probing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to find the key


while (hashTable[index] != key && hashTable[index] != -1) {
index = (index + 1) % size;
}

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)

10
for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table


for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);
}

// Print the hash table


printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}

return 0;
}
OUTPUT:-

11
DIGIT EXTRACTION:-
#include <stdio.h>

#define SIZE 10 // Size of the hash table

// Hash function using digit extraction


int hashFunction(int key, int size) {
return key % 10; // Extract the last digit
}

// Insert function for linear probing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to handle collisions


while (hashTable[index] != -1) {
index = (index + 1) % size;
}

hashTable[index] = key;
}

// Search function for linear probing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to find the key


while (hashTable[index] != key && hashTable[index] != -1) {
index = (index + 1) % size;
}

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)


for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table

12
for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);
}

// Print the hash table


printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}

return 0;
}
OUTPUT:-

FOLD SHIFT:-
#include <stdio.h>

#define SIZE 10 // Size of the hash table

// Hash function using fold-shift


int hashFunction(int key, int size) {
int hash = 0;

// Fold the key into chunks of 2 digits and add them up


while (key > 0) {
hash += key % 100;
key /= 100;

13
}

// Shift the result to fit into the table size


return hash % size;
}

// Insert function for linear probing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to handle collisions


while (hashTable[index] != -1) {
index = (index + 1) % size;
}

hashTable[index] = key;
}

// Search function for linear probing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to find the key


while (hashTable[index] != key && hashTable[index] != -1) {
index = (index + 1) % size;
}

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)


for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table


for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);
}

14
// Print the hash table
printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}

return 0;
}

OUTPUT:-

FOLD BOUNDARY:-
#include <stdio.h>

#define SIZE 10 // Size of the hash table

// Hash function using fold boundary


int hashFunction(int key, int size) {
int hash = 0;
int boundary = 100; // Set the fold boundary

// Fold the key into chunks determined by the boundary and add them
up
while (key > 0) {
hash += key % boundary;
key /= boundary;

15
}

// Take the modulus to fit into the table size


return hash % size;
}

// Insert function for linear probing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to handle collisions


while (hashTable[index] != -1) {
index = (index + 1) % size;
}

hashTable[index] = key;
}

// Search function for linear probing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to find the key


while (hashTable[index] != key && hashTable[index] != -1) {
index = (index + 1) % size;
}

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)


for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table


for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);
}

16
// Print the hash table
printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}

return 0;
}
OUTPUT:-

LINEAR PROBE FOR COLLISION RESOLUTION:-


Already used in above code.
#include <stdio.h>

#define SIZE 10 // Size of the hash table

// Hash function using fold boundary


int hashFunction(int key, int size) {
int hash = 0;
int boundary = 100; // Set the fold boundary

// Fold the key into chunks determined by the boundary and add them
up
while (key > 0) {

17
hash += key % boundary;
key /= boundary;
}

// Take the modulus to fit into the table size


return hash % size;
}

// Insert function for linear probing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to handle collisions


while (hashTable[index] != -1) {
index = (index + 1) % size;
}

hashTable[index] = key;
}

// Search function for linear probing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to find the key


while (hashTable[index] != key && hashTable[index] != -1) {
index = (index + 1) % size;
}

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)


for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table


for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);

18
}

// Print the hash table


printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}

return 0;
}
OUTPUT:-

DIRECT HASHING:-
#include <stdio.h>

#define SIZE 10 // Size of the hash table

// Hash function using direct hashing


int hashFunction(int key, int size) {
return key % size; // Use the key directly as an index
}

// Insert function for direct hashing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Directly insert at the calculated index


hashTable[index] = key;

19
}

// Search function for direct hashing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)


for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table


for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);
}

// Print the hash table


printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}

return 0;
}

20
OUTPUT:-

SUBTRACTION HASHING:-
#include <stdio.h>

#define SIZE 10 // Size of the hash table


#define SUBTRACTION_VALUE 5 // Value to subtract in subtraction hashing

// Hash function using subtraction hashing


int hashFunction(int key, int size) {
return (key - SUBTRACTION_VALUE) % size;
}

// Insert function for linear probing


void insert(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to handle collisions


while (hashTable[index] != -1) {
index = (index + 1) % size;
}

hashTable[index] = key;
}

// Search function for linear probing


int search(int hashTable[], int size, int key) {
int index = hashFunction(key, size);

// Linear probing to find the key


while (hashTable[index] != key && hashTable[index] != -1) {
index = (index + 1) % size;
}

// If the key is found, return the index; otherwise, return -1


return (hashTable[index] == key) ? index : -1;
}

21
int main() {
int hashTable[SIZE];

// Initialize hash table with -1 (indicating empty slots)


for (int i = 0; i < SIZE; i++) {
hashTable[i] = -1;
}

// Set of numbers to insert and search


int numbers[] = {10, 25, 7, 42, 15, 31, 19, 5, 28, 12};
int n = sizeof(numbers) / sizeof(numbers[0]);

// Insert numbers into the hash table


for (int i = 0; i < n; i++) {
insert(hashTable, SIZE, numbers[i]);
}

// Print the hash table


printf("Hash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("%d: %d\n", i, hashTable[i]);
}

// Search for a key in the hash table


int keyToSearch = 15;
int result = search(hashTable, SIZE, keyToSearch);

if (result != -1) {
printf("Element %d found at index %d.\n", keyToSearch, result);
} else {
printf("Element %d not found in the hash table.\n",
keyToSearch);
}
return 0;
}
OUTPUT:-

22
EXPERIMENT:-03

OBJECTIVE:-

Implementing Stacks: Array implementation, Linked List implementation, Evaluation of postfix


expression and balancing of parenthesis , Conversion of infix notation to postfix notation.

CODE:-

IMPLEMENTING STACKS:-

ARRAY IMPLEMENTATION:-
#include <stdio.h>
#include <stdbool.h>

#define MAX_SIZE 100 // Maximum size of the stack

// Structure to represent a stack


struct Stack {
int arr[MAX_SIZE];
int top;
};

// Function to initialize an empty stack


void initializeStack(struct Stack *stack) {
stack->top = -1; // Set the top index to -1 to indicate an empty
stack
}

// Function to check if the stack is empty


bool isEmpty(struct Stack *stack) {
return stack->top == -1;
}

// Function to check if the stack is full


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

// Function to push an element onto the stack


void push(struct Stack *stack, int value) {
if (isFull(stack)) {
printf("Stack Overflow: Cannot push %d, the stack is full.\n",
value);
} else {
stack->top++;

23
stack->arr[stack->top] = value;
printf("Pushed %d onto the stack.\n", value);
}
}

// Function to pop an element from the stack


int pop(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack Underflow: Cannot pop from an empty stack.\n");
return -1; // Return a sentinel value indicating underflow
} else {
int poppedValue = stack->arr[stack->top];
stack->top--;
printf("Popped %d from the stack.\n", poppedValue);
return poppedValue;
}
}

// Function to get the top element of the stack without popping


int peek(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty.\n");
return -1; // Return a sentinel value indicating empty stack
} else {
return stack->arr[stack->top];
}
}

// Function to print the elements of the stack


void printStack(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty.\n");
} else {
printf("Stack elements: ");
for (int i = 0; i <= stack->top; i++) {
printf("%d ", stack->arr[i]);
}
printf("\n");
}
}

int main() {
struct Stack stack;
initializeStack(&stack);

push(&stack, 10);
push(&stack, 20);
push(&stack, 30);

24
printStack(&stack);

printf("Top element: %d\n", peek(&stack));

pop(&stack);
pop(&stack);

printStack(&stack);

printf("Top element: %d\n", peek(&stack));

pop(&stack);

return 0;
}
OUTPUT:-

LINKED LIST IMPLEMENTATION:-


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

// Structure to represent a node in the linked list


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

// Structure to represent a stack


struct Stack {
struct Node *top;
};

// Function to initialize an empty stack


void initializeStack(struct Stack *stack) {
stack->top = NULL; // Set the top pointer to NULL to indicate an
empty stack
}

// Function to check if the stack is empty

25
bool isEmpty(struct Stack *stack) {
return stack->top == NULL;
}

// Function to push an element onto the stack


void push(struct Stack *stack, int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed. Cannot push %d.\n", value);
return;
}

newNode->data = value;
newNode->next = stack->top;
stack->top = newNode;

printf("Pushed %d onto the stack.\n", value);


}

// Function to pop an element from the stack


int pop(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack Underflow: Cannot pop from an empty stack.\n");
return -1; // Return a sentinel value indicating underflow
} else {
struct Node *temp = stack->top;
int poppedValue = temp->data;
stack->top = temp->next;
free(temp);
printf("Popped %d from the stack.\n", poppedValue);
return poppedValue;
}
}

// Function to get the top element of the stack without popping


int peek(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty.\n");
return -1; // Return a sentinel value indicating empty stack
} else {
return stack->top->data;
}
}

// Function to print the elements of the stack


void printStack(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Stack is empty.\n");

26
} else {
printf("Stack elements: ");
struct Node *current = stack->top;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}
}

// Function to free the memory allocated for the stack


void freeStack(struct Stack *stack) {
while (stack->top != NULL) {
struct Node *temp = stack->top;
stack->top = temp->next;
free(temp);
}
}

int main() {
struct Stack stack;
initializeStack(&stack);

push(&stack, 10);
push(&stack, 20);
push(&stack, 30);

printStack(&stack);

printf("Top element: %d\n", peek(&stack));

pop(&stack);
pop(&stack);

printStack(&stack);

printf("Top element: %d\n", peek(&stack));


pop(&stack);

// Free the memory allocated for the stack


freeStack(&stack);

return 0;
}

27
OUTPUT:-

EVALUATION OF POSTFIX EXPRESSION:-


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

// Structure to represent a node in the stack


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

// Structure to represent a stack


struct Stack {
struct Node *top;
};

// Function to initialize an empty stack


void initializeStack(struct Stack *stack) {
stack->top = NULL;
}

// Function to check if the stack is empty


int isEmpty(struct Stack *stack) {
return stack->top == NULL;
}

// Function to push an element onto the stack


void push(struct Stack *stack, int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed. Cannot push %d.\n", value);
exit(EXIT_FAILURE);
}

newNode->data = value;
newNode->next = stack->top;
stack->top = newNode;

28
}

// Function to pop an element from the stack


int pop(struct Stack *stack) {
if (isEmpty(stack)) {
printf("Error: Stack underflow.\n");
exit(EXIT_FAILURE);
} else {
struct Node *temp = stack->top;
int poppedValue = temp->data;
stack->top = temp->next;
free(temp);
return poppedValue;
}
}

// Function to perform arithmetic operations


int performOperation(int operand1, int operand2, char operator) {
switch (operator) {
case '+':
return operand1 + operand2;
case '-':
return operand1 - operand2;
case '*':
return operand1 * operand2;
case '/':
if (operand2 == 0) {
printf("Error: Division by zero.\n");
exit(EXIT_FAILURE);
}
return operand1 / operand2;
default:
printf("Error: Invalid operator.\n");
exit(EXIT_FAILURE);
}
}

// Function to evaluate a postfix expression


int evaluatePostfix(char postfix[]) {
struct Stack stack;
initializeStack(&stack);

for (int i = 0; postfix[i] != '\0'; i++) {


if (isdigit(postfix[i])) {
push(&stack, postfix[i] - '0'); // Convert character to
integer
} else {
int operand2 = pop(&stack);

29
int operand1 = pop(&stack);
int result = performOperation(operand1, operand2,
postfix[i]);
push(&stack, result);
}
}

if (!isEmpty(&stack) && [Link]->next == NULL) {


return pop(&stack);
} else {
printf("Error: Invalid postfix expression.\n");
exit(EXIT_FAILURE);
}
}

int main() {
char postfixExpression[] = "23*5+";
int result = evaluatePostfix(postfixExpression);
printf("Result of postfix expression %s is: %d\n",
postfixExpression, result);

return 0;
}
OUTPUT

BALANCING OF PARENTHESIS:-
#include <stdio.h>
#include <stdlib.h>
#include <string.h> // Include the string.h header

// Define a structure for the stack


struct Stack {
int top;
unsigned capacity;
char* array;
};

// Function to create a stack


struct Stack* createStack(unsigned capacity) {
struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (char*)malloc(stack->capacity * sizeof(char));
return stack;
}

30
// Function to check if the stack is empty
int isEmpty(struct Stack* stack) {
return stack->top == -1;
}

// Function to push an element onto the stack


void push(struct Stack* stack, char item) {
stack->array[++stack->top] = item;
}

// Function to pop an element from the stack


char pop(struct Stack* stack) {
if (!isEmpty(stack))
return stack->array[stack->top--];
return '\0';
}

// Function to check if parentheses are balanced


int areParenthesesBalanced(char* exp) {
struct Stack* stack = createStack(strlen(exp));

for (int i = 0; exp[i]; i++) {


if (exp[i] == '(' || exp[i] == '{' || exp[i] == '[') {
push(stack, exp[i]);
} else if (exp[i] == ')' || exp[i] == '}' || exp[i] == ']') {
if (isEmpty(stack)) {
free(stack->array);
free(stack);
return 0; // Unbalanced parentheses
}

char popped = pop(stack);


if ((exp[i] == ')' && popped != '(') ||
(exp[i] == '}' && popped != '{') ||
(exp[i] == ']' && popped != '[')) {
free(stack->array);
free(stack);
return 0; // Unbalanced parentheses
}
}
}

int result = isEmpty(stack); // Check if there are unmatched opening


parentheses left

free(stack->array);
free(stack);

31
return result;
}

int main() {
char expression[100];

printf("Enter the expression: ");


fgets(expression, sizeof(expression), stdin);

if (areParenthesesBalanced(expression)) {
printf("The parentheses are balanced.\n");
} else {
printf("The parentheses are not balanced.\n");
}

return 0;
}
OUTPUT

CONVERSION OF INFIX NOTATION TO POSTFIX NOTATION:-


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

// Structure to represent a stack


struct Stack {
int top;
unsigned capacity;
char* array;
};

// Function to create a stack


struct Stack* createStack(unsigned capacity) {
struct Stack* stack = (struct Stack*)malloc(sizeof(struct Stack));
stack->capacity = capacity;
stack->top = -1;
stack->array = (char*)malloc(stack->capacity * sizeof(char));
return stack;
}

// Function to check if the stack is empty


int isEmpty(struct Stack* stack) {
return stack->top == -1;
}

32
// Function to push an element onto the stack
void push(struct Stack* stack, char item) {
stack->array[++stack->top] = item;
}

// Function to pop an element from the stack


char pop(struct Stack* stack) {
if (!isEmpty(stack))
return stack->array[stack->top--];
return '\0';
}

// Function to get the top element from the stack without popping
char peek(struct Stack* stack) {
if (!isEmpty(stack))
return stack->array[stack->top];
return '\0';
}

// Function to check if a character is an operator


int isOperator(char ch) {
return (ch == '+' || ch == '-' || ch == '*' || ch == '/');
}

// Function to get the precedence of an operator


int precedence(char ch) {
if (ch == '+' || ch == '-')
return 1;
else if (ch == '*' || ch == '/')
return 2;
return 0;
}

// Function to convert infix expression to postfix expression


void infixToPostfix(char* infix, char* postfix) {
struct Stack* stack = createStack(strlen(infix));
int i, j;

for (i = 0, j = 0; infix[i]; i++) {


// If the scanned character is an operand, add it to the output
if ((infix[i] >= 'a' && infix[i] <= 'z') || (infix[i] >= 'A' &&
infix[i] <= 'Z')) {
postfix[j++] = infix[i];
}
// If the scanned character is an '(', push it onto the stack
else if (infix[i] == '(') {
push(stack, infix[i]);

33
}
// If the scanned character is an ')', pop and output from the
stack until '(' is encountered
else if (infix[i] == ')') {
while (!isEmpty(stack) && peek(stack) != '(') {
postfix[j++] = pop(stack);
}
if (!isEmpty(stack) && peek(stack) != '(') {
printf("Invalid expression\n");
return;
} else {
pop(stack); // Discard the '(' from the stack
}
}
// If an operator is encountered
else if (isOperator(infix[i])) {
while (!isEmpty(stack) && precedence(infix[i]) <=
precedence(peek(stack))) {
postfix[j++] = pop(stack);
}
push(stack, infix[i]);
}
}

// Pop all the remaining operators from the stack


while (!isEmpty(stack)) {
postfix[j++] = pop(stack);
}

postfix[j] = '\0'; // Null-terminate the postfix expression


}

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

printf("Enter the infix expression: ");


scanf("%s", infix);

infixToPostfix(infix, postfix);

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

return 0;
}
OUTPUT:-

34
EXPERIMENT:-04

OBJECTIVE:-

Implementing Queue: Linked List implementation of ordinary queue, Array implementation of


circular queue, Linked List implementation of priority queue, Double ended queue

CODE:-

LINKED LIST IMPLEMENTATION OF ORDINARY QUEUE :-


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

// Node structure for the linked list


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

// Queue structure
struct Queue {
struct Node* front;
struct Node* rear;
};

// Function to create a new node


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

// Function to initialize an empty queue


struct Queue* createQueue() {
struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
if (queue == NULL) {
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
queue->front = queue->rear = NULL;
return queue;
}

35
// Function to check if the queue is empty
int isEmpty(struct Queue* queue) {
return (queue->front == NULL);
}

// Function to enqueue an element into the queue


void enqueue(struct Queue* queue, int value) {
struct Node* newNode = createNode(value);
if (isEmpty(queue)) {
queue->front = queue->rear = newNode;
} else {
queue->rear->next = newNode;
queue->rear = newNode;
}
}

// Function to dequeue an element from the queue


int dequeue(struct Queue* queue) {
if (isEmpty(queue)) {
printf("Queue is empty, cannot dequeue\n");
exit(EXIT_FAILURE);
}

int value = queue->front->data;


struct Node* temp = queue->front;

if (queue->front == queue->rear) {
queue->front = queue->rear = NULL;
} else {
queue->front = queue->front->next;
}

free(temp);
return value;
}

// Function to display the elements in the queue


void displayQueue(struct Queue* queue) {
if (isEmpty(queue)) {
printf("Queue is empty\n");
return;
}

struct Node* current = queue->front;


while (current != NULL) {
printf("%d ", current->data);
current = current->next;

36
}
printf("\n");
}

// Function to free the memory allocated for the queue


void freeQueue(struct Queue* queue) {
while (!isEmpty(queue)) {
dequeue(queue);
}
free(queue);
}

int main() {
struct Queue* queue = createQueue();

enqueue(queue, 10);
enqueue(queue, 20);
enqueue(queue, 30);

printf("Queue elements: ");


displayQueue(queue);

printf("Dequeued element: %d\n", dequeue(queue));

printf("Queue elements after dequeue: ");


displayQueue(queue);

freeQueue(queue);

return 0;
}

OUTPUT:-

37
ARRAY IMPLEMENTATION OF CIRCULAR QUEUE:-
#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 5

// Circular Queue structure


struct CircularQueue {
int front, rear;
int array[MAX_SIZE];
};

// Function to initialize an empty circular queue


void initializeQueue(struct CircularQueue* queue) {
queue->front = queue->rear = -1;
}

// Function to check if the circular queue is empty


int isEmpty(struct CircularQueue* queue) {
return (queue->front == -1 && queue->rear == -1);
}

// Function to check if the circular queue is full


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

// Function to enqueue an element into the circular queue


void enqueue(struct CircularQueue* queue, int value) {
if (isFull(queue)) {
printf("Queue is full, cannot enqueue\n");
return;
}

if (isEmpty(queue)) {
queue->front = queue->rear = 0;
} else {
queue->rear = (queue->rear + 1) % MAX_SIZE;
}

queue->array[queue->rear] = value;
}

// Function to dequeue an element from the circular queue


int dequeue(struct CircularQueue* queue) {
int value;

if (isEmpty(queue)) {

38
printf("Queue is empty, cannot dequeue\n");
exit(EXIT_FAILURE);
}

value = queue->array[queue->front];

if (queue->front == queue->rear) {
initializeQueue(queue);
} else {
queue->front = (queue->front + 1) % MAX_SIZE;
}

return value;
}

// Function to display the elements in the circular queue


void displayQueue(struct CircularQueue* queue) {
int i;
if (isEmpty(queue)) {
printf("Queue is empty\n");
return;
}

printf("Queue elements: ");


i = queue->front;
do {
printf("%d ", queue->array[i]);
i = (i + 1) % MAX_SIZE;
} while (i != (queue->rear + 1) % MAX_SIZE);

printf("\n");
}

int main() {
struct CircularQueue queue;
initializeQueue(&queue);

enqueue(&queue, 10);
enqueue(&queue, 20);
enqueue(&queue, 30);
enqueue(&queue, 40);
enqueue(&queue, 50);

displayQueue(&queue);

printf("Dequeued element: %d\n", dequeue(&queue));

enqueue(&queue, 60);

39
displayQueue(&queue);

return 0;
}

OUTPUT:-

LINKED LIST IMPLEMENTATION OF PRIORITY QUEUE:-


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

// Node structure for the linked list


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

// Priority Queue structure


struct PriorityQueue {
struct Node* front;
};

// Function to create a new node


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

// Function to initialize an empty priority queue

40
struct PriorityQueue* createPriorityQueue() {
struct PriorityQueue* pq = (struct
PriorityQueue*)malloc(sizeof(struct PriorityQueue));
if (pq == NULL) {
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
pq->front = NULL;
return pq;
}

// Function to enqueue an element into the priority queue


void enqueue(struct PriorityQueue* pq, int value, int priority) {
struct Node* newNode = createNode(value, priority);

// If the priority queue is empty or the new node has higher


priority than the front
if (pq->front == NULL || priority > pq->front->priority) {
newNode->next = pq->front;
pq->front = newNode;
} else {
struct Node* current = pq->front;

// Traverse the list to find the correct position to insert the


new node
while (current->next != NULL && priority <= current->next-
>priority) {
current = current->next;
}

newNode->next = current->next;
current->next = newNode;
}
}

// Function to dequeue an element from the priority queue


int dequeue(struct PriorityQueue* pq) {
if (pq->front == NULL) {
printf("Priority Queue is empty, cannot dequeue\n");
exit(EXIT_FAILURE);
}

int value = pq->front->data;


struct Node* temp = pq->front;
pq->front = pq->front->next;
free(temp);

return value;

41
}

// Function to display the elements in the priority queue


void displayPriorityQueue(struct PriorityQueue* pq) {
if (pq->front == NULL) {
printf("Priority Queue is empty\n");
return;
}

struct Node* current = pq->front;


while (current != NULL) {
printf("Value: %d, Priority: %d\n", current->data, current-
>priority);
current = current->next;
}
}

// Function to free the memory allocated for the priority queue


void freePriorityQueue(struct PriorityQueue* pq) {
while (pq->front != NULL) {
dequeue(pq);
}
free(pq);
}

int main() {
struct PriorityQueue* pq = createPriorityQueue();

enqueue(pq, 10, 2);


enqueue(pq, 20, 1);
enqueue(pq, 30, 3);

printf("Priority Queue elements:\n");


displayPriorityQueue(pq);

printf("Dequeued element: %d\n", dequeue(pq));

printf("Priority Queue elements after dequeue:\n");


displayPriorityQueue(pq);

freePriorityQueue(pq);

return 0;
}

42
OUTPUT:-

DOUBLE ENDED QUEUE:-


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

// Node structure for the doubly linked list


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

// Double-Ended Queue structure


struct Deque {
struct Node* front;
struct Node* rear;
};

// Function to create a new node


struct Node* createNode(int value) {
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
newNode->data = value;

43
newNode->prev = NULL;
newNode->next = NULL;
return newNode;
}

// Function to initialize an empty deque


struct Deque* createDeque() {
struct Deque* deque = (struct Deque*)malloc(sizeof(struct Deque));
if (deque == NULL) {
printf("Memory allocation failed\n");
exit(EXIT_FAILURE);
}
deque->front = deque->rear = NULL;
return deque;
}

// Function to check if the deque is empty


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

// Function to insert an element at the front of the deque


void insertFront(struct Deque* deque, int value) {
struct Node* newNode = createNode(value);

if (isEmpty(deque)) {
deque->front = deque->rear = newNode;
} else {
newNode->next = deque->front;
deque->front->prev = newNode;
deque->front = newNode;
}
}

// Function to insert an element at the rear of the deque


void insertRear(struct Deque* deque, int value) {
struct Node* newNode = createNode(value);

if (isEmpty(deque)) {
deque->front = deque->rear = newNode;
} else {
newNode->prev = deque->rear;
deque->rear->next = newNode;
deque->rear = newNode;
}
}

44
// Function to delete an element from the front of the deque
int deleteFront(struct Deque* deque) {
if (isEmpty(deque)) {
printf("Deque is empty, cannot delete from the front\n");
exit(EXIT_FAILURE);
}

int value = deque->front->data;


struct Node* temp = deque->front;

if (deque->front == deque->rear) {
deque->front = deque->rear = NULL;
} else {
deque->front = deque->front->next;
deque->front->prev = NULL;
}

free(temp);
return value;
}

// Function to delete an element from the rear of the deque


int deleteRear(struct Deque* deque) {
if (isEmpty(deque)) {
printf("Deque is empty, cannot delete from the rear\n");
exit(EXIT_FAILURE);
}

int value = deque->rear->data;


struct Node* temp = deque->rear;

if (deque->front == deque->rear) {
deque->front = deque->rear = NULL;
} else {
deque->rear = deque->rear->prev;
deque->rear->next = NULL;
}

free(temp);
return value;
}

// Function to display the elements in the deque from front to rear


void displayDeque(struct Deque* deque) {
if (isEmpty(deque)) {
printf("Deque is empty\n");
return;
}

45
struct Node* current = deque->front;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}

// Function to free the memory allocated for the deque


void freeDeque(struct Deque* deque) {
while (!isEmpty(deque)) {
deleteFront(deque);
}
free(deque);
}

int main() {
struct Deque* deque = createDeque();

insertFront(deque, 10);
insertFront(deque, 20);
insertRear(deque, 30);
insertRear(deque, 40);

printf("Deque elements from front to rear: ");


displayDeque(deque);

printf("Deleted element from the front: %d\n", deleteFront(deque));

printf("Deleted element from the rear: %d\n", deleteRear(deque));

printf("Deque elements after deletion: ");


displayDeque(deque);

freeDeque(deque);

return 0;
}
OUTPUT:-

46
EXPERIMENT:-05

OBJECTIVE:-

Implementing Linked List: Singly Linked Lists, Circular Linked List, Doubly Linked Lists :
Insert, Display, Delete, Search, Count, Reverse(SLL), Polynomial , Addition

CODE:-

SINGLY LINKED LISTS:-


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

// Node structure for the linked list


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

// Function to create a new node


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

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


struct Node* insertAtBeginning(struct Node* head, int value) {
struct Node* newNode = createNode(value);
newNode->next = head;
return newNode;
}

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


struct Node* insertAtEnd(struct Node* head, int value) {
struct Node* newNode = createNode(value);
if (head == NULL) {
return newNode;
}

struct Node* current = head;


while (current->next != NULL) {
current = current->next; }

47
current->next = newNode;
return head;
}

// Function to insert a new node at a specific position in the linked


list
struct Node* insertAtPosition(struct Node* head, int value, int
position) {
if (position < 1) {
printf("Invalid position\n");
return head;
}

struct Node* newNode = createNode(value);

if (position == 1) {
newNode->next = head;
return newNode;
}

struct Node* current = head;


for (int i = 1; i < position - 1 && current != NULL; i++) {
current = current->next;
}

if (current == NULL) {
printf("Invalid position\n");
return head;
}

newNode->next = current->next;
current->next = newNode;
return head;
}

// Function to delete a node at the beginning of the linked list


struct Node* deleteAtBeginning(struct Node* head) {
if (head == NULL) {
printf("List is empty, cannot delete from the beginning\n");
return head;
}

struct Node* temp = head;


head = head->next;
free(temp);
return head;
}

48
// Function to delete a node at the end of the linked list
struct Node* deleteAtEnd(struct Node* head) {
if (head == NULL) {
printf("List is empty, cannot delete from the end\n");
return head;
}

if (head->next == NULL) {
free(head);
return NULL;
}

struct Node* current = head;


while (current->next->next != NULL) {
current = current->next;
}

free(current->next);
current->next = NULL;
return head;
}

// Function to display the elements in the linked list


void displayList(struct Node* head) {
struct Node* current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}

// Function to free the memory allocated for the linked list


void freeList(struct Node* head) {
while (head != NULL) {
struct Node* temp = head;
head = head->next;
free(temp);
}
}

int main() {
struct Node* head = NULL;

head = insertAtEnd(head, 10);


head = insertAtEnd(head, 20);
head = insertAtBeginning(head, 5);
head = insertAtPosition(head, 15, 2);

49
printf("Linked list elements: ");
displayList(head);

head = deleteAtBeginning(head);
head = deleteAtEnd(head);

printf("Linked list elements after deletion: ");


displayList(head);

freeList(head);

return 0;
}

OUTPUT:-

CIRCULAR LINKED LIST:-


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

// Node structure for the circular linked list


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

// Function to create a new node


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

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


list

50
struct Node* insertAtBeginning(struct Node* head, int value) {
struct Node* newNode = createNode(value);

if (head == NULL) {
newNode->next = newNode; // Point to itself for the first node
return newNode;
}

// Find the last node in the circular linked list


struct Node* last = head;
while (last->next != head) {
last = last->next;
}

// Insert the new node at the beginning


newNode->next = head;
last->next = newNode;
return newNode;
}

// Function to insert a new node at the end of the circular linked list
struct Node* insertAtEnd(struct Node* head, int value) {
struct Node* newNode = createNode(value);

if (head == NULL) {
newNode->next = newNode; // Point to itself for the first node
return newNode;
}

// Find the last node in the circular linked list


struct Node* last = head;
while (last->next != head) {
last = last->next;
}

// Insert the new node at the end


newNode->next = head;
last->next = newNode;
return head;
}

// Function to display the elements in the circular linked list


void displayList(struct Node* head) {
if (head == NULL) {
printf("Circular linked list is empty\n");
return;
}

51
struct Node* current = head;
do {
printf("%d ", current->data);
current = current->next;
} while (current != head);

printf("\n");
}

// Function to free the memory allocated for the circular linked list
void freeList(struct Node* head) {
if (head == NULL) {
return;
}

struct Node* current = head;


struct Node* temp;

do {
temp = current;
current = current->next;
free(temp);
} while (current != head);
}

int main() {
struct Node* head = NULL;

head = insertAtEnd(head, 10);


head = insertAtEnd(head, 20);
head = insertAtBeginning(head, 5);

printf("Circular Linked List elements: ");


displayList(head);

freeList(head);

return 0;
}

OUTPUT:-

52
DOUBLY LINKED LISTS :

INSERT, DISPLAY, DELETE, SEARCH, COUNT, REVERSE(SLL), POLYNOMIAL ,


ADDITION

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

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

typedef struct Node Node;

Node* createNode(int value) {


Node* newNode = (Node*)malloc(sizeof(Node));
newNode->data = value;
newNode->next = NULL;
newNode->prev = NULL;
return newNode;
}

Node* insertAtBeginning(Node* head, int value) {


Node* newNode = createNode(value);
if (head != NULL) {
newNode->next = head;
head->prev = newNode;
}
return newNode;
}

Node* insertAtEnd(Node* head, int value) {


Node* newNode = createNode(value);
if (head == NULL) {
return newNode;
}

Node* current = head;


while (current->next != NULL) {
current = current->next;
}

current->next = newNode;
newNode->prev = current;
return head;

53
}

Node* deleteNode(Node* head, int key) {


Node* current = head;
while (current != NULL && current->data != key) {
current = current->next;
}

if (current == NULL) {
return head;
}

if (current->prev != NULL) {
current->prev->next = current->next;
} else {
head = current->next;
}

if (current->next != NULL) {
current->next->prev = current->prev;
}

free(current);
return head;
}

Node* search(Node* head, int key) {


Node* current = head;
while (current != NULL && current->data != key) {
current = current->next;
}
return current;
}

int countNodes(Node* head) {


int count = 0;
Node* current = head;
while (current != NULL) {
count++;
current = current->next;
}
return count;
}

Node* reverseList(Node* head) {


Node *current = head, *temp = NULL;
while (current != NULL) {
temp = current->prev;

54
current->prev = current->next;
current->next = temp;
current = current->prev;
}
if (temp != NULL) {
head = temp->prev;
}
return head;
}

void displayList(Node* head) {


Node* current = head;
while (current != NULL) {
printf("%d ", current->data);
current = current->next;
}
printf("\n");
}

Node* addPolynomials(Node* poly1, Node* poly2) {


Node* result = NULL;
while (poly1 != NULL && poly2 != NULL) {
if (poly1->data > poly2->data) {
result = insertAtEnd(result, poly1->data);
poly1 = poly1->next;
} else if (poly1->data < poly2->data) {
result = insertAtEnd(result, poly2->data);
poly2 = poly2->next;
} else {
result = insertAtEnd(result, poly1->data);
poly1 = poly1->next;
poly2 = poly2->next;
}
}
while (poly1 != NULL) {
result = insertAtEnd(result, poly1->data);
poly1 = poly1->next;
}
while (poly2 != NULL) {
result = insertAtEnd(result, poly2->data);
poly2 = poly2->next;
}
return result;
}

void freeList(Node* head) {


Node* current = head;
Node* next;

55
while (current != NULL) {
next = current->next;
free(current);
current = next;
}
}

int main() {
Node* list = NULL;
list = insertAtEnd(list, 10);
list = insertAtEnd(list, 20);
list = insertAtBeginning(list, 5);

printf("Original Doubly Linked List: ");


displayList(list);

list = deleteNode(list, 20);

printf("Doubly Linked List after deletion: ");


displayList(list);

int keyToSearch = 10;


Node* searchResult = search(list, keyToSearch);
if (searchResult != NULL) {
printf("Node with data %d found.\n", keyToSearch);
} else {
printf("Node with data %d not found.\n", keyToSearch);
}

printf("Number of nodes in the list: %d\n", countNodes(list));

list = reverseList(list);
printf("Reversed Doubly Linked List: ");
displayList(list);

Node* poly1 = NULL;


Node* poly2 = NULL;
poly1 = insertAtEnd(poly1, 2);
poly1 = insertAtEnd(poly1, 4);
poly1 = insertAtEnd(poly1, 6);

poly2 = insertAtEnd(poly2, 1);


poly2 = insertAtEnd(poly2, 3);
poly2 = insertAtEnd(poly2, 5);

Node* resultPoly = addPolynomials(poly1, poly2);


printf("Result of Polynomial Addition: ");
displayList(resultPoly);

56
// Free memory
freeList(list);
freeList(poly1);
freeList(poly2);
freeList(resultPoly);

return 0;
}
OUTPUT:-

57
EXPERIMENT:-06

OBJECTIVE:-

IMPLEMENTING TREES: BINARY SEARCH TREE : Create, Recursive traversal:


preorder, post order, in order, Search Largest , Node, Smallest Node, Count number of nodes
Heap: Min Heap, Max Heap: reheap Up, reheap Down, Delete , Expression Tree, Heapsort.

CODE:-

BINARY SEARCH TREE : CREATE, RECURSIVE TRAVERSAL: PREORDER, POST


ORDER, IN ORDER, SEARCH LARGEST , NODE, SMALLEST NODE, COUNT
NUMBER OF NODES

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

// Structure for a node in the BST


struct Node {
int data;
struct Node *left;
struct Node *right;
};

// Function to create a new node


struct Node *createNode(int value) {
struct Node *newNode = (struct Node *)malloc(sizeof(struct Node));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(EXIT_FAILURE);
}

newNode->data = value;
newNode->left = NULL;
newNode->right = NULL;

return newNode;
}

// Function to insert a value into the BST


struct Node *insert(struct Node *root, int value) {
if (root == NULL) {
return createNode(value);
}

if (value < root->data) {

58
root->left = insert(root->left, value);
} else if (value > root->data) {
root->right = insert(root->right, value);
}

return root;
}

// Function for in-order traversal (left, root, right)


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

// Function for pre-order traversal (root, left, right)


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

// Function for post-order traversal (left, right, root)


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

// Function to find the node with the largest value in the BST
struct Node *findLargestNode(struct Node *root) {
while (root->right != NULL) {
root = root->right;
}
return root;
}

// Function to find the node with the smallest value in the BST
struct Node *findSmallestNode(struct Node *root) {
while (root->left != NULL) {
root = root->left;
}

59
return root;
}

// Function to count the number of nodes in the BST


int countNodes(struct Node *root) {
if (root == NULL) {
return 0;
}
return 1 + countNodes(root->left) + countNodes(root->right);
}

int main() {
// Create an empty BST
struct Node *root = NULL;

// Insert values 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);

// Perform recursive traversals


printf("In-order traversal: ");
inorderTraversal(root);
printf("\n");

printf("Pre-order traversal: ");


preorderTraversal(root);
printf("\n");

printf("Post-order traversal: ");


postorderTraversal(root);
printf("\n");

// Search for the largest and smallest nodes


struct Node *largestNode = findLargestNode(root);
struct Node *smallestNode = findSmallestNode(root);

printf("Largest Node: %d\n", largestNode->data);


printf("Smallest Node: %d\n", smallestNode->data);

// Count the number of nodes


int nodeCount = countNodes(root);
printf("Number of nodes in the BST: %d\n", nodeCount);
return 0:}

60
OUTPUT:-

HEAP:
MIN HEAP,MAX HEAP: REHEAP UP, REHEAP DOWN, DELETE , EXPRESSION
TREE, HEAPSORT.
#include <stdio.h>
#include <stdlib.h>

// Structure to represent a heap


struct Heap {
int* array;
int capacity;
int size;
};

// Function to create a new heap


struct Heap* createHeap(int capacity) {
struct Heap* heap = (struct Heap*)malloc(sizeof(struct Heap));
heap->array = (int*)malloc(sizeof(int) * capacity);
heap->capacity = capacity;
heap->size = 0;
return heap;
}

// Function to swap two elements in the heap


void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}

// Function to heapify the heap upwards


void reheapUp(struct Heap* heap, int index) {
while (index > 0 && heap->array[index] < heap->array[(index - 1) /
2]) {

61
swap(&heap->array[index], &heap->array[(index - 1) / 2]);
index = (index - 1) / 2;
}
}

// Function to heapify the heap downwards


void reheapDown(struct Heap* heap, int index) {
int left = 2 * index + 1;
int right = 2 * index + 2;
int smallest = index;

if (left < heap->size && heap->array[left] < heap->array[smallest])


{
smallest = left;
}

if (right < heap->size && heap->array[right] < heap-


>array[smallest]) {
smallest = right;
}

if (smallest != index) {
swap(&heap->array[index], &heap->array[smallest]);
reheapDown(heap, smallest);
}
}

// Function to insert a new element into the heap


void insert(struct Heap* heap, int value) {
if (heap->size == heap->capacity) {
printf("Heap overflow\n");
return;
}

heap->array[heap->size] = value;
heap->size++;
reheapUp(heap, heap->size - 1);
}

// Function to delete the minimum element from the heap


int deleteMin(struct Heap* heap) {
if (heap->size <= 0) {
printf("Heap underflow\n");
return -1;
}

int min = heap->array[0];


heap->array[0] = heap->array[heap->size - 1];

62
heap->size--;
reheapDown(heap, 0);

return min;
}

// Function to create an expression tree


struct ExpressionTreeNode {
char value;
struct ExpressionTreeNode* left;
struct ExpressionTreeNode* right;
};

struct ExpressionTreeNode* createExpressionTreeNode(char value) {


struct ExpressionTreeNode* node = (struct
ExpressionTreeNode*)malloc(sizeof(struct ExpressionTreeNode));
node->value = value;
node->left = NULL;
node->right = NULL;
return node;
}

// Function to perform heapsort


void heapsort(int arr[], int n) {
struct Heap* heap = createHeap(n);

// Insert elements into the heap


for (int i = 0; i < n; i++) {
insert(heap, arr[i]);
}

// Extract elements from the heap and put them back into the array
for (int i = 0; i < n; i++) {
arr[i] = deleteMin(heap);
}

// Free the allocated memory for the heap


free(heap->array);
free(heap);
}

int main() {
// Example usage

// Min Heap
struct Heap* minHeap = createHeap(10);
insert(minHeap, 4);
insert(minHeap, 2);

63
insert(minHeap, 7);
insert(minHeap, 1);

printf("Min Heap: %d ", deleteMin(minHeap)); // Output: 1


printf("%d ", deleteMin(minHeap)); // Output: 2
printf("%d\n", deleteMin(minHeap)); // Output: 4

// Max Heap
struct Heap* maxHeap = createHeap(10);
maxHeap->array[0] = 4;
maxHeap->array[1] = 2;
maxHeap->array[2] = 7;
maxHeap->array[3] = 1;
maxHeap->size = 4;

printf("Max Heap: %d ", deleteMin(maxHeap)); // Output: 7


printf("%d ", deleteMin(maxHeap)); // Output: 4
printf("%d\n", deleteMin(maxHeap)); // Output: 2

// Expression Tree
struct ExpressionTreeNode* root = createExpressionTreeNode('*');
root->left = createExpressionTreeNode('+');
root->right = createExpressionTreeNode('-');
root->left->left = createExpressionTreeNode('2');
root->left->right = createExpressionTreeNode('3');
root->right->left = createExpressionTreeNode('5');
root->right->right = createExpressionTreeNode('4');

// Heapsort
int arr[] = {12, 11, 13, 5, 6, 7};
int n = sizeof(arr) / sizeof(arr[0]);
heapsort(arr, n);

printf("Sorted array: ");


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

return 0;
}
OUTPUT:-

64
EXPERIMENT:-07

OBJECTIVE:-

Implementing Graphs: Represent a graph using the Adjacency Matrix, BFS, Find the minimum
spanning tree (using any method Kruskal’s Algorithm or Prim’s Algorithm) Self Learning Topics :
Shortest Path Algorithm

CODE:-

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

// Maximum number of vertices in the graph


#define MAX_VERTICES 100

// Structure to represent an undirected, weighted graph


struct Graph {
int vertices;
int** adjacencyMatrix;
};

// Function to create a new graph with a given number of vertices


struct Graph* createGraph(int vertices) {
struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
graph->vertices = vertices;

// Allocate memory for the adjacency matrix


graph->adjacencyMatrix = (int**)malloc(vertices * sizeof(int*));
for (int i = 0; i < vertices; i++) {
graph->adjacencyMatrix[i] = (int*)malloc(vertices *
sizeof(int));
for (int j = 0; j < vertices; j++) {
graph->adjacencyMatrix[i][j] = 0; // Initialize all entries
to 0
}
}

return graph;
}

// Function to add an edge to the graph


void addEdge(struct Graph* graph, int source, int destination, int
weight) {
// Assuming the graph is undirected
graph->adjacencyMatrix[source][destination] = weight;

65
graph->adjacencyMatrix[destination][source] = weight;
}

// Function to perform Breadth-First Search (BFS)


void BFS(struct Graph* graph, int startVertex) {
int* visited = (int*)malloc(graph->vertices * sizeof(int));
for (int i = 0; i < graph->vertices; i++) {
visited[i] = 0; // Initialize all vertices as not visited
}

int queue[MAX_VERTICES];
int front = -1, rear = -1;

visited[startVertex] = 1;
queue[++rear] = startVertex;

while (front != rear) {


int currentVertex = queue[++front];
printf("%d ", currentVertex);

for (int i = 0; i < graph->vertices; i++) {


if (graph->adjacencyMatrix[currentVertex][i] && !visited[i])
{
visited[i] = 1;
queue[++rear] = i;
}
}
}

free(visited);
}

// Structure to represent an edge in the graph


struct Edge {
int source, destination, weight;
};

// Structure to represent a subset for Union-Find


struct Subset {
int parent, rank;
};

// Function to find the set of an element in Union-Find


int find(struct Subset subsets[], int i) {
if (subsets[i].parent != i) {
subsets[i].parent = find(subsets, subsets[i].parent);
}
return subsets[i].parent;

66
}

// Function to perform Union of two sets in Union-Find


void unionSets(struct Subset subsets[], int x, int y) {
int xroot = find(subsets, x);
int yroot = find(subsets, y);

if (subsets[xroot].rank < subsets[yroot].rank) {


subsets[xroot].parent = yroot;
} else if (subsets[xroot].rank > subsets[yroot].rank) {
subsets[yroot].parent = xroot;
} else {
subsets[yroot].parent = xroot;
subsets[xroot].rank++;
}
}

// Function to compare two edges based on weight (used for sorting)


int compareEdges(const void* a, const void* b) {
return ((struct Edge*)a)->weight - ((struct Edge*)b)->weight;
}

// Function to find the minimum spanning tree using Kruskal's Algorithm


void kruskalMST(struct Graph* graph) {
int vertices = graph->vertices;
struct Edge* edges = (struct Edge*)malloc(vertices * vertices *
sizeof(struct Edge));

// Extracting edges from the adjacency matrix


int edgeCount = 0;
for (int i = 0; i < vertices; i++) {
for (int j = i + 1; j < vertices; j++) {
if (graph->adjacencyMatrix[i][j] != 0) {
edges[edgeCount].source = i;
edges[edgeCount].destination = j;
edges[edgeCount].weight = graph->adjacencyMatrix[i][j];
edgeCount++;
}
}
}

// Sort edges in ascending order based on weight


qsort(edges, edgeCount, sizeof(struct Edge), compareEdges);

// Allocate memory for the subsets array


struct Subset* subsets = (struct Subset*)malloc(vertices *
sizeof(struct Subset));

67
// Initialize subsets
for (int i = 0; i < vertices; i++) {
subsets[i].parent = i;
subsets[i].rank = 0;
}

printf("Minimum Spanning Tree using Kruskal's Algorithm:\n");


for (int i = 0; i < edgeCount; i++) {
int x = find(subsets, edges[i].source);
int y = find(subsets, edges[i].destination);

if (x != y) {
printf("%d - %d : %d\n", edges[i].source,
edges[i].destination, edges[i].weight);
unionSets(subsets, x, y);
}
}

free(edges);
free(subsets);
}

// Function to find the index of the vertex with the minimum distance
value
int minDistance(int distance[], int visited[], int vertices) {
int min = INT_MAX, minIndex;

for (int v = 0; v < vertices; v++) {


if (!visited[v] && distance[v] < min) {
min = distance[v];
minIndex = v;
}
}

return minIndex;
}

// Function to print the constructed distance array


void printShortestPath(int distance[], int n) {
printf("Vertex Distance from Source\n");
for (int i = 0; i < n; i++) {
printf("%d \t\t %d\n", i, distance[i]);
}
}

// Function to implement Dijkstra's algorithm for finding the shortest


path
void dijkstra(struct Graph* graph, int startVertex) {

68
int vertices = graph->vertices;
int* distance = (int*)malloc(vertices * sizeof(int));
int* visited = (int*)malloc(vertices * sizeof(int));

for (int i = 0; i < vertices; i++) {


distance[i] = INT_MAX;
visited[i] = 0;
}

distance[startVertex] = 0;

for (int count = 0; count < vertices - 1; count++) {


int u = minDistance(distance, visited, vertices);
visited[u] = 1;

for (int v = 0; v < vertices; v++) {


if (!visited[v] && graph->adjacencyMatrix[u][v] &&
distance[u] != INT_MAX &&
distance[u] + graph->adjacencyMatrix[u][v] <
distance[v]) {
distance[v] = distance[u] + graph-
>adjacencyMatrix[u][v];
}
}
}

printf("Shortest Paths from Vertex %d using Dijkstra's


Algorithm:\n", startVertex);
printShortestPath(distance, vertices);

free(distance);
free(visited);
}

int main() {
// Example usage

// Create a graph with 5 vertices


struct Graph* graph = createGraph(5);

// Add edges to the graph


addEdge(graph, 0, 1, 2);
addEdge(graph, 0, 3, 1);
addEdge(graph, 1, 2, 4);
addEdge(graph, 1, 3, 3);
addEdge(graph, 1, 4, 5);
addEdge(graph, 2, 4, 1);
addEdge(graph, 3, 4, 7);

69
// Perform BFS starting from vertex 0
printf("Breadth-First Search (BFS) starting from vertex 0:\n");
BFS(graph, 0);
printf("\n");

// Find the minimum spanning tree using Kruskal's Algorithm


kruskalMST(graph);

// Find the shortest paths using Dijkstra's Algorithm starting from


vertex 0
dijkstra(graph, 0);

// Free allocated memory for the graph


for (int i = 0; i < graph->vertices; i++) {
free(graph->adjacencyMatrix[i]);
}
free(graph->adjacencyMatrix);
free(graph);

return 0;
}

OUTPUT:-

70

You might also like