0% found this document useful (0 votes)
55 views70 pages

DS Lab Manual R23 Final

The document provides a comprehensive overview of various data structures and algorithms in C, including array manipulation, searching techniques (linear and binary search), and sorting algorithms (bubble, selection, and insertion sort). It also covers linked list implementation with operations such as insertion, deletion, and reversal both iteratively and recursively. Additionally, it discusses key concepts related to linked list traversal and manipulation.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views70 pages

DS Lab Manual R23 Final

The document provides a comprehensive overview of various data structures and algorithms in C, including array manipulation, searching techniques (linear and binary search), and sorting algorithms (bubble, selection, and insertion sort). It also covers linked list implementation with operations such as insertion, deletion, and reversal both iteratively and recursively. Additionally, it discusses key concepts related to linked list traversal and manipulation.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 70

Information Technology

Exercise 1: Array Manipulation

i. Write a program to reverse an array.


#include <stdio.h>
#define N 1000
int main() {
int arr[N];
int n;
// Inputting the size of the array
printf("Enter the size of the array: ");
scanf("%d", &n);
// Inputting the array
printf("Enter an array: ");
for (int i = 0; i< n; i++){
scanf("%d", &arr[i]);
}
printf(".....original array is.....\n");
for (int i = 0; i< n; i++){
printf("%d ", arr[i]);
}
// Printing the reverse of the array
printf("\n......Reversed array is......\n");
for (int i = n-1; i>=0; i--){
printf("%d ", arr[i]);
}
return 0;
}
Output:
Enter the size of the array: 5
Enter an array: 2
9
8
4
0
.....original array is.....
29840
......Reversed array is......
0 4892
Information Technology

ii. C Programs to implement the Searching Techniques – Linear & Binary Search
Linear Search
#include<stdio.h>
int main() {
// declaration of the array and other variables
int arr[20], size, key, i, index;
int countKey = 0; //initializing count of key element as 0
printf("...enter size of array.... ");
scanf("%d", &size);
printf(".....Enter elements of the array..... ");
// loop for the input of elements from 0 to number of elements-1
for (i = 0; i < size; i++)
scanf("%d", &arr[i]);
printf("....elements of array..... \n");
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n.....Enter the element to search.....\n");
scanf("%d", &key);
// loop for traversing the array from 0 to the number of elements-1
for (index = 0; index < size; index++) {
if (arr[index] == key) { // comparing each element with the key element
printf("Key element found at index %d\n", index); // printing the index if key found
countKey++; // incrementing the count of key element;
}
}
if (countKey == 0) // condition to check whether key element is found or not
printf("Key element not found");
else
printf("Key element is present %d times in the array.\n", countKey);
return 0;
}
Output:
...enter size of array.... 5
.....Enter elements of the array..... 2
4
2
8
2
....elements of array.....
24282
.....Enter the element to search.....
2
Key element found at index 0
Key element found at index 2
Key element found at index 4
Key element is present 3 times in the array.
Information Technology

Binary Search

#include <stdio.h>
int binarySearch(int array[], int x, int low, int high) {
// Repeat until the pointers low and high meet each other
while (low <= high) {
int mid = low + (high - low) / 2;
if (array[mid] == x)
return mid;
if (array[mid] < x)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
int main(void) {
int arr[100], size, key, i, index;
printf("...enter size of array.... ");
scanf("%d", &size);
printf(".....Enter elements of the array..... ");
// loop for the input of elements from 0 to number of elements-1
for (i = 0; i < size; i++)
scanf("%d", &arr[i]);
printf("....elements of array..... \n");
for (i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n.....Enter the element to search.....\n");
scanf("%d", &key);
int result = binarySearch(arr, key, 0, size);
if (result == -1)
printf("Not found");
else
printf("Element is found at index %d", result);
return 0;
}
Output:
...enter size of array.... 5
.....Enter elements of the array..... 2
4
8
1
6
....elements of array.....
24816
.....Enter the element to search.....
8
Element is found at index 2
Information Technology

iii. C Programs to implement Sorting Techniques – Bubble, Selection and Insertion Sort
Bubble sort
// C program for implementation of Bubble sort
#include <stdio.h>
int main(){
int arr[50], num, x, y, temp;
printf("Enter size of the array: ");
scanf("%d", &num);
printf("......Enter array Elements......");
for(x = 0; x < num; x++)
scanf("%d", &arr[x]);
printf("......array Elements are......\n");
for(x = 0; x < num; x++)
printf("%d ", arr[x]);
for(x = 0; x < num - 1; x++){
for(y = 0; y < num - x - 1; y++){
if(arr[y] > arr[y + 1]){
temp = arr[y];
arr[y] = arr[y + 1];
arr[y + 1] = temp;
}
}
}
printf("\n.....Array after bubble sort bubble sort......\n");
for(x = 0; x < num; x++){
printf("%d ", arr[x]);
}
return 0;
}
Output:
Enter size of the array: 5
......Enter array Elements......3
1
7
5
0
......array Elements are......
3 1 7 5 0
.....Array after bubble sort bubble sort......
0 1 3 5 7
Information Technology

Selection sort
// C program for implementation of Selection sort
#include <stdio.h>
int main()
{
int array[100], n, c, d, position, t;
printf(".....Enter number of elements....\n");
scanf("%d", &n);
printf("....Enter %d integers....\n", n);
for (c = 0; c < n; c++)
scanf("%d", &array[c]);
printf("....Array elements are....\n");
for (c = 0; c < n; c++)
printf("%d ", array[c]);
for (c = 0; c < (n - 1); c++) // finding minimum element (n-1) times
{
position = c;
for (d = c + 1; d < n; d++)
{
if (array[position] > array[d])
position = d;
}
if (position != c)
{
t = array[c];
array[c] = array[position];
array[position] = t;
}
}
printf("\n....Sorted list in ascending order.....\n");
for (c = 0; c < n; c++)
printf("%d ", array[c]);
return 0;
}
Output:
.....Enter number of elements....
5
....Enter 5 integers....
4
2
9
3
6
....Array elements are .....
4 2 9 3 6
....Sorted list in ascending order.....
2 3 4 6 9
Information Technology

Insertion sort
// C program for implementation of insertion sort
#include <stdio.h>
int main(void)
{
int n, i, j, temp;
int arr[64];
printf("....Enter number of elements.....\n");
scanf("%d", &n);
printf(".....Enter %d integers....\n", n);
for (i = 0; i < n; i++)
{
scanf("%d", &arr[i]);
}
printf("\n....array elements are.....\n");
for (i = 0; i < n; i++)
{ printf("%d ", arr[i]); }
for (i = 1; i < n; i++)
{
j = i;
while (j > 0 && arr[j - 1] > arr[j])
{
temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
j--;
}
}
printf("\n.....Sorted list in ascending order.....\n");
for (i = 0; i < n; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
Output:
....Enter number of elements.....
5
.....Enter 5 integers....
7
9
3
6
11
....array elements are.....
7 9 3 6 11
.....Sorted list in ascending order.....
3 6 7 9 11
Information Technology

Exercise 2: Linked List Implementation


i) Implement a singly linked list and perform insertion and deletion operations.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
void insertAtBeginning(struct Node** head, int value) {
// Create a new node
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// Set the value of the new node
newNode->data = value;
// Point the new node to the current head
newNode->next = *head;
// Update the head to point to the new node
*head = newNode;
}
void deleteAtBeginning(struct Node** head) {
if (*head == NULL) {
printf("........Linked list is already empty......\n");
return;
}
struct Node* temp = *head;
*head = (*head)->next;
free(temp);
}
void deleteAtEnd(struct Node** head) {
if (*head == NULL) {
printf(".....Linked list is already empty.....\n");
return;
}
struct Node* temp = *head;
struct Node* prev = NULL;
while (temp->next != NULL) {
prev = temp;
temp = temp->next;
}
if (prev == NULL) {
*head = NULL;
} else {
prev->next = NULL;
}
free(temp);
}
void deleteAtPosition(struct Node** head, int position) {
if (*head == NULL) {
printf("....Linked list is already empty.......\n");
Information Technology

return;
}
struct Node* temp = *head;
struct Node* prev = NULL;
if (position == 1) {
*head = temp->next;
free(temp);
return;
}
for (int i = 1; temp != NULL && i < position; i++) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) {
printf(".....Invalid position.....\n");
return;
}
prev->next = temp->next;
free(temp);
}
void displayList(struct Node* head) {
struct Node* temp = head;
// Traverse and print the list
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
printf("\n");
}
int main() {
struct Node* head = NULL;
// Insert elements at the beginning
insertAtBeginning(&head, 1);
insertAtBeginning(&head, 2);
insertAtBeginning(&head, 3);
insertAtBeginning(&head, 4);
insertAtBeginning(&head, 5);
// Display the original list
printf("........Linked List....... ");
displayList(head);
// Delete node at the beginning
deleteAtBeginning(&head);
// Display the list after deletion at the beginning
printf(".....Linked List after deletion at the beginning.... ");
displayList(head);
// Delete node at the end
deleteAtEnd(&head);
// Display the list after deletion at the end
Information Technology

printf("....Linked List after deletion at the end....");


displayList(head);
// Delete node at a specific position
deleteAtPosition(&head, 1);
// Display the list after deletion at a specific position
printf(".....Linked List after deletion at a specific position....");
displayList(head);
return 0;
}
Output:
........Linked List....... 5 4 3 2 1
.....Linked List after deletion at the beginning.... 4 3 2 1
....Linked List after deletion at the end....4 3 2
.....Linked List after deletion at a specific position....3 2
Information Technology

ii) Develop a program to reverse a linked list iteratively and recursively.

Iterative C program to reverse a linked list


#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
/* Function to reverse the linked list */
static void reverse(struct Node** head_ref)
{
struct Node* prev = NULL;
struct Node* current = *head_ref;
struct Node* next = NULL;
while (current != NULL) {
// Store next
next = current->next;

// Reverse current node's pointer


current->next = prev;

// Move pointers one position ahead.


prev = current;
current = next;
}
*head_ref = prev;
}
/* Function to push a node */
void push(struct Node** head_ref, int new_data)
{
struct Node* new_node
= (struct Node*)malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
/* Function to print linked list */
void printList(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL) {
printf("%d ", temp->data);
temp = temp->next;
}
}
/* Driver code*/
int main()
Information Technology

{
/* Start with the empty list */
struct Node* head = NULL;
push(&head, 20);
push(&head, 4);
push(&head, 15);
push(&head, 85);
printf(".....Given linked list is ......\n");
printList(head);
reverse(&head);
printf("\n.......Reversed linked list is........ \n");
printList(head);
getchar();
}
Output:
.....Given linked list is ......
85 15 4 20
.......Reversed linked list is........
20 4 15 85

//Recursive C program to reverse linked list


#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node *next;
};
void print_reverse_recursive (struct node *);
void print (struct node *);
void create_new_node (struct node *, int );
//Driver Function
int main ()
{
struct node *head = NULL;
insert_new_node (&head, 1);
insert_new_node (&head, 2);
insert_new_node (&head, 3);
insert_new_node (&head, 4);
printf ("......LinkedList.....");
print (head);
printf ("\n....LinkedList in reverse order....");
print_reverse_recursive (head);
printf ("\n");
return 0;
}
//Recursive Reverse
void print_reverse_recursive (struct node *head)
Information Technology

{
if (head == NULL)
{
return;
}
//Recursive call first
print_reverse_recursive (head -> next);
//Print later
printf ("%d ", head -> data);
}
//Print the linkedlist normal
void print (struct node *head)
{
if (head == NULL)
{
return;
}
printf ("%d ", head -> data);
print (head -> next);
}
//New data added in the start
void insert_new_node (struct node ** head_ref, int new_data)
{
struct node * new_node = (struct node *) malloc (sizeof (struct node));
new_node -> data = new_data;
new_node -> next = (*head_ref);
(*head_ref) = new_node;
}
Output:
......LinkedList.....4 3 2 1
....LinkedList in reverse order....1 2 3 4
Information Technology

iii) Solve problems involving linked list traversal and manipulation.

 Traversal - access each element of the linked list


Manipulation
 Insertion - adds a new element to the linked list
 Deletion - removes the existing elements
 Search - find a node in the linked list
 Sort - sort the nodes of the linked list

Things to Remember about Linked List


 head points to the first node of the linked list
 next pointer of the last node is NULL, so if the next current node is NULL, we have reached the
end of the linked list.
In all of the examples, we will assume that the linked list has three nodes 1 --->2 --->3 with node
structure as below:

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

Traverse a Linked List


Displaying the contents of a linked list is very simple. We keep moving the temp node to the next
one and display its contents.
When temp is NULL, we know that we have reached the end of the linked list so we get out of the
while loop.

struct node *temp = head;


printf("\n\nList elements are - \n");
while(temp != NULL) {
printf("%d --->",temp->data);
temp = temp->next;
}

The output of this program will be:

List elements are -


1 --->2 --->3 --->

Insert Elements to a Linked List


You can add elements to either the beginning, middle or end of the linked list.
1. Insert at the beginning
 Allocate memory for new node
 Store data
 Change next of new node to point to head
 Change head to point to recently created node
Information Technology

struct node *newNode;


newNode = malloc(sizeof(struct node));
newNode->data = 4;
newNode->next = head;
head = newNode;

2. Insert at the End


 Allocate memory for new node
 Store data
 Traverse to last node
 Change next of last node to recently created node

struct node *newNode;


newNode = malloc(sizeof(struct node));
newNode->data = 4;
newNode->next = NULL;

struct node *temp = head;


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

temp->next = newNode;

3. Insert at the Middle


 Allocate memory and store data for new node
 Traverse to node just before the required position of new node
 Change next pointers to include new node in between

struct node *newNode;


newNode = malloc(sizeof(struct node));
newNode->data = 4;

struct node *temp = head;

for(int i=2; i < position; i++) {


if(temp->next != NULL) {
temp = temp->next;
}
}
newNode->next = temp->next;
temp->next = newNode;

Delete from a Linked List


You can delete either from the beginning, end or from a particular position.
1. Delete from beginning
 Point head to the second node
Information Technology

head = head->next;

2. Delete from end


 Traverse to second last element
 Change its next pointer to null

struct node* temp = head;


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

3. Delete from middle


 Traverse to element before the element to be deleted
 Change next pointers to exclude the node from the chain

for(int i=2; i< position; i++) {


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

temp->next = temp->next->next;

Search an Element on a Linked List


You can search an element on a linked list using a loop using the following steps. We are
finding item on a linked list.
 Make head as the current node.
 Run a loop until the current node is NULL because the last element points to NULL.
 In each iteration, check if the key of the node is equal to item. If it the key matches the item,
return true otherwise return false.

// Search a node
bool searchNode(struct Node** head_ref, int key) {
struct Node* current = *head_ref;

while (current != NULL) {


if (current->data == key) return true;
current = current->next;
}
return false;
}

Sort Elements of a Linked List


We will use a simple sorting algorithm, Bubble Sort, to sort the elements of a linked list in
ascending order below.
1. Make the head as the current node and create another node index for later use.
Information Technology

2. If head is null, return.


3. Else, run a loop till the last node (i.e. NULL).
4. In each iteration, follow the following step 5-6.
5. Store the next node of current in index.
6. Check if the data of the current node is greater than the next node. If it is greater,
swap current and index.
Check the article on bubble sort for better understanding of its working.

// Sort the linked list


void sortLinkedList(struct Node** head_ref) {
struct Node *current = *head_ref, *index = NULL;
int temp;

if (head_ref == NULL) {
return;
} else {
while (current != NULL) {
// index points to the node next to current
index = current->next;

while (index != NULL) {


if (current->data > index->data) {
temp = current->data;
current->data = index->data;
index->data = temp;
}
index = index->next;
}
current = current->next;
}
}
}
Information Technology

Exercise 3: Linked List Applications

i) Create a program to detect and remove duplicates from a linked list.


#include <stdio.h>
#include <stdlib.h>
struct Node
{
int data;
struct Node *next;
} *first = NULL;
void create(int A[], int n)
{
int i;
struct Node *t, *last;
first = (struct Node *) malloc (sizeof (struct Node));
first->data = A[0];
first->next = NULL;
last = first;
for (i = 1; i < n; i++)
{
t = (struct Node *) malloc (sizeof (struct Node));
t->data = A[i];
t->next = NULL;
last->next = t;
last = t;
}
}
void display(struct Node *p)
{
while (p != NULL)
{
printf ("%d ", p->data);
p = p->next;
}
}
void removeDuplicate(struct Node *p)
{
struct Node *q = p->next;
while (q != NULL)
{
if (p->data != q->data)
{
p = q;
q = q->next;
}
else
{
p->next = q->next;
Information Technology

free(q);
q = p->next;
}
}
}
int main()
{
int A[] = { 33, 33, 8, 8, 8 };
create (A, 5);
printf ("......Linked List with Duplicates..... \n");
display (first);
removeDuplicate (first);
printf ("\n......Linked List without Duplicates....... \n");
display (first);
return 0;
}
Output:
......Linked List with Duplicates.....
33 33 8 8 8
......Linked List without Duplicates.......
33
Information Technology

ii) Implement a linked list to represent polynomials and perform addition.


#include <stdio.h>
#include <stdlib.h>
struct Node {
int coef;
int exp;
struct Node* next;
};
typedef struct Node Node;
void insert(Node** poly, int coef, int exp) {
Node* temp = (Node*) malloc(sizeof(Node));
temp->coef = coef;
temp->exp = exp;
temp->next = NULL;
if (*poly == NULL) {
*poly = temp;
return;
}
Node* current = *poly;
while (current->next != NULL) {
current = current->next;
}
current->next = temp;
}
void print(Node* poly) {
if (poly == NULL) {
printf("0\n");
return;
}
Node* current = poly;
while (current != NULL) {
printf("%dx^%d", current->coef, current->exp);
if (current->next != NULL) {
printf(" + ");
}
current = current->next;
}
printf("\n");
}
Node* add(Node* poly1, Node* poly2) {
Node* result = NULL;
while (poly1 != NULL && poly2 != NULL) {
if (poly1->exp == poly2->exp) {
insert(&result, poly1->coef + poly2->coef, poly1->exp);
poly1 = poly1->next;
poly2 = poly2->next;
} else if (poly1->exp > poly2->exp) {
insert(&result, poly1->coef, poly1->exp);
Information Technology

poly1 = poly1->next;
} else {
insert(&result, poly2->coef, poly2->exp);
poly2 = poly2->next;
}
}
while (poly1 != NULL) {
insert(&result, poly1->coef, poly1->exp);
poly1 = poly1->next;
}
while (poly2 != NULL) {
insert(&result, poly2->coef, poly2->exp);
poly2 = poly2->next;
}
return result;
}
int main() {
Node* poly1 = NULL;
insert(&poly1, 5, 4);
insert(&poly1, 3, 2);
insert(&poly1, 1, 0);
Node* poly2 = NULL;
insert(&poly2, 4, 4);
insert(&poly2, 2, 2);
insert(&poly2, 1, 1);
printf("First polynomial: ");
print(poly1);
printf("Second polynomial: ");
print(poly2);
Node* result = add(poly1, poly2);
printf("Result: ");
print(result);
return 0;
}
Output:
First polynomial: 5x^4 + 3x^2 + 1x^0
Second polynomial: 4x^4 + 2x^2 + 1x^1
Result: 9x^4 + 5x^2 + 1x^1 + 1x^0
Information Technology

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


#include <stdio.h>
#define size 5
int deque[size];
int f = -1, r = -1;
// insert_front function will insert the value from the front
void insert_front(int x)
{
if((f==0 && r==size-1) || (f==r+1))
{
printf("Overflow");
}
else if((f==-1) && (r==-1))
{
f=r=0;
deque[f]=x;
}
else if(f==0)
{
f=size-1;
deque[f]=x;
}
else
{
f=f-1;
deque[f]=x;
}
}
// insert_rear function will insert the value from the rear
void insert_rear(int x)
{
if((f==0 && r==size-1) || (f==r+1))
{
printf("Overflow");
}
else if((f==-1) && (r==-1))
{
r=0;
deque[r]=x;
}
else if(r==size-1)
{
r=0;
deque[r]=x;
}
else
{
r++;
Information Technology

deque[r]=x;
}

}
// display function prints all the value of deque.
void display()
{
int i=f;
printf("\nElements in a deque are: ");

while(i!=r)
{
printf("%d ",deque[i]);
i=(i+1)%size;
}
printf("%d",deque[r]);
}
// getfront function retrieves the first value of the deque.
void getfront()
{
if((f==-1) && (r==-1))
{
printf("Deque is empty");
}
else
{
printf("\nThe value of the element at front is: %d", deque[f]);
}

}
// getrear function retrieves the last value of the deque.
void getrear()
{
if((f==-1) && (r==-1))
{
printf("Deque is empty");
}
else
{
printf("\nThe value of the element at rear is: %d", deque[r]);
}
}
// delete_front() function deletes the element from the front
void delete_front()
{
if((f==-1) && (r==-1))
{
printf("Deque is empty");
Information Technology

}
else if(f==r)
{
printf("\nThe deleted element at front is:%d", deque[f]);
f=-1;
r=-1;
}
else if(f==(size-1))
{
printf("\nThe deleted element at front is:%d", deque[f]);
f=0;
}
else
{
printf("\nThe deleted element at front is:%d", deque[f]);
f=f+1;
}
}
// delete_rear() function deletes the element from the rear
void delete_rear()
{
if((f==-1) && (r==-1))
{
printf("Deque is empty");
}
else if(f==r)
{
printf("\nThe deleted element at rear is: %d", deque[r]);
f=-1;
r=-1;
}
else if(r==0)
{
printf("\nThe deleted element at rear is: %d", deque[r]);
r=size-1;
}
else
{
printf("\nThe deleted element at rear is: %d", deque[r]);
r=r-1;
}
}
int main()
{
insert_front(200);
insert_front(100);
insert_rear(300);
insert_rear(500);
Information Technology

insert_rear(800);
display(); // Calling the display function to retrieve the values of deque
getfront(); // Retrieve the value at front-end
getrear(); // Retrieve the value at rear-end
delete_front();
delete_rear();
display(); // calling display function to retrieve values after deletion
return 0;
}
Output:
Elements in a deque are: 100 200 300 500 800
The value of the element at front is: 100
The value of the element at rear is: 800
The deleted element at front is:100
The deleted element at rear is: 800
Elements in a deque are: 200 300 500
Information Technology

Exercise 4: Double Linked List Implementation

i) Implement a doubly linked list and perform various operations to


understand its properties and applications.

(Note: you can ignore writing comments in observation or record; those are
mentioned just for u r understanding purpose of code)
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
struct Node* prev;
};
void insertAtFront(struct Node** head, int data) {
// Create a new struct node and allocate memory.
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// Initialize data in the newly created node.
newNode->data = data;
// Make the next pointer of the new node point to the head.
// In this way, this new node is added at front of the linked list.
newNode->next = (*head);
newNode->prev = NULL;
// If the head is not NULL, then we update the prev pointer in the current head.
// The prev pointer of the current head will point to the new node.
if((*head) != NULL) {
(*head)->prev = newNode;
}
// Update the head pointer to point to the new node.
(*head) = newNode;
}
void insertAtEnd(struct Node** head, int data) {
// Create a new struct node and allocate memory.
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// Initialize data in the newly created node.
newNode->data = data;
newNode->next = NULL;
if((*head) == NULL) {
// If the head is NULL, then the new node is the new head.
newNode->prev = NULL;
// Assign head as the new node.
(*head) = newNode;
return ;
}
// If the list is not empty then traverse to the end of the list.
struct Node* ptr = (*head);
while(ptr->next != NULL) {
ptr = ptr->next;
Information Technology

}
// From the last node, add a link to the new node.
ptr->next = newNode;
// Update the prev pointer in the new node to point to the previous last node.
newNode->prev = ptr;
}
void insertAfterNode(struct Node* node, int data) {
if(node == NULL) {
// If the node is NULL, then we cannot insert.
printf("The given node cannot be NULL.");
return ;
}
// Create a new struct node and allocate memory.
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// Initialize data in the newly created node.
newNode->data = data;
// Add a link from new node to next_node.
newNode->next = node->next;
// Add a link from the given node to the new node.
node->next = newNode;
// Update the prev pointer of the new node to the given node.
newNode->prev = node;
// If the next_node is not NULL, then update the prev of the next_node.
if(newNode->next != NULL) {
newNode->next->prev = newNode;
}
}
void insertBeforeNode(struct Node** head, struct Node* node, int data) {
if(node == NULL) {
// If the given node is NULL, then we cannot insert a node before a NULL node.
printf("The given node cannot be NULL.");
return ;
}
// Create a new struct node and allocate memory.
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// Initialize data in the newly created node.
newNode->data = data;
// Add a link from the new node to the given node.
newNode->next = node;
if(node->prev != NULL) {
// If the given node is not the head node, then we update the next pointer of previous node
node->prev->next = newNode;
// Update the prev pointer of the new node to point to the previous node.
newNode->prev = node->prev;
}
else {
// If the previous value is NULL, then this means the given node is head.
// So we are inserting it at the front of head.
Information Technology

// Hence, we update the value of the head pointer to the new node.
*head = newNode;
}
// Update the previous pointer of the given node.
node->prev = newNode;
}
void deleteAtFront(struct Node** head) {
// If the head pointer is NULL, then we cannot delete it.
if((*head) == NULL) return ;
struct Node* curr = *head;
// Update the head pointer to the next node.
*head = (*head)->next;
// Make the previous head pointer NULL and free the memory.
curr->next = NULL;
free(curr);
}
void deleteAtLast(struct Node** head) {
// If the head pointer is NULL, then we cannot delete it.
if((*head) == NULL) return ;
// Traverse to the last node.
struct Node* curr = *head;
while(curr->next != NULL) {
curr = curr->next;
}
// Second last node will point to NULL.
struct Node* prev = curr->prev;
prev->next = NULL;
// Make the last node NULL and free the memory.
curr->prev = NULL;
free(curr);
}
void deleteAtPosition(struct Node** head, int position) {
struct Node* curr = *head;
if(position == 1) {
// If the position is 1, then delete the head and return.
deleteAtFront(head);
return ;
}
// Go the node to be deleted.
while(position > 1 && curr) {
// While the position is greater than 1 and the current node is not NULL,
// we iterate forward and decrease position by 1.
curr = curr->next;
position --;
}
// If the current node is NULL, then we cannot delete it.
// The node at the specified position does not exist.
if(curr == NULL) {
Information Technology

printf("Node at position is not present.\n");


return ;
}
// Create pointers to the previous node and the next node of the current node.
struct Node* prevNode = curr->prev;
struct Node* nextNode = curr->next;
// Update the next pointer of the previous node and the previous pointer of the next node.
// In this way, the middle node is removed from the list.
curr->prev->next = nextNode;
if(nextNode != NULL) {
nextNode->prev = prevNode;
}
// Remove the link to the list and free the memory.
curr->next = curr->prev = NULL;
free(curr);
}
void traverse(struct Node* head) {
for(struct Node* i = head; i != NULL; i = i->next) {
printf("%d", i->data);
if(i->next) printf(" <--> ");
}
printf(" -> NULL \n");
}
int main() {
struct Node* head = NULL;
printf("Insert 1 at the front\n");
insertAtFront(&head, 1);
traverse(head);
printf("Insert 2 at the front\n");
insertAtFront(&head, 2);
traverse(head);
printf("Insert 4 at the end\n");
insertAtEnd(&head, 4);
traverse(head);
printf("Insert 5 at the front\n");
insertAtEnd(&head, 5);
traverse(head);
printf("Insert 3 after head->next\n");
insertAfterNode(head->next, 3);
traverse(head);
printf("Insert -1 before the head\n");
insertBeforeNode(&head, head, -1);
traverse(head);
printf("Insert 100 before head->next->next\n");
insertBeforeNode(&head, head->next->next, 100);
traverse(head);
printf("Delete the front node.\n");
deleteAtFront(&head);
Information Technology

traverse(head);
printf("Delete the last node\n");
deleteAtLast(&head);
traverse(head);
printf("Delete the second node from the front.\n");
deleteAtPosition(&head, 2);
traverse(head);
return 0;
}
Output:
Insert 1 at the front
1 -> NULL
Insert 2 at the front
2 <--> 1 -> NULL
Insert 4 at the end
2 <--> 1 <--> 4 -> NULL
Insert 5 at the front
2 <--> 1 <--> 4 <--> 5 -> NULL
Insert 3 after head->next
2 <--> 1 <--> 3 <--> 4 <--> 5 -> NULL
Insert -1 before the head
-1 <--> 2 <--> 1 <--> 3 <--> 4 <--> 5 -> NULL
Insert 100 before head->next->next
-1 <--> 2 <--> 100 <--> 1 <--> 3 <--> 4 <--> 5 -> NULL
Delete the front node.
2 <--> 100 <--> 1 <--> 3 <--> 4 <--> 5 -> NULL
Delete the last node
2 <--> 100 <--> 1 <--> 3 <--> 4 -> NULL
Delete the second node from the front.
1 <--> 1 <--> 3 <--> 4 -> NULL
Information Technology

ii) Implement a circular linked list and perform insertion, deletion, and traversal.

(Note: you can ignore writing comments in observation or record; those are
mentioned just for u r understanding purpose of code)
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node* next;
};
struct Node* addToEmpty(struct Node* last, int data) {
if (last != NULL) return last;
// allocate memory to the new node
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// assign data to the new node
newNode->data = data;
// assign last to newNode
last = newNode;
// create link to iteself
last->next = last;
return last;
}
// add node to the front
struct Node* addFront(struct Node* last, int data) {
// check if the list is empty
if (last == NULL) return addToEmpty(last, data);
// allocate memory to the new node
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// add data to the node
newNode->data = data;
// store the address of the current first node in the newNode
newNode->next = last->next;
// make newNode as head
last->next = newNode;
return last;
}
// add node to the end
struct Node* addEnd(struct Node* last, int data) {
// check if the node is empty
if (last == NULL) return addToEmpty(last, data);
// allocate memory to the new node
struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
// add data to the node
newNode->data = data;
// store the address of the head node to next of newNode
newNode->next = last->next;
// point the current last node to the newNode
last->next = newNode;
Information Technology

// make newNode as the last node


last = newNode;
return last;
}
// insert node after a specific node
struct Node* addAfter(struct Node* last, int data, int item) {
// check if the list is empty
if (last == NULL) return NULL;
struct Node *newNode, *p;
p = last->next;
do {
// if the item is found, place newNode after it
if (p->data == item) {
// allocate memory to the new node
newNode = (struct Node*)malloc(sizeof(struct Node));
// add data to the node
newNode->data = data;
// make the next of the current node as the next of newNode
newNode->next = p->next;
// put newNode to the next of p
p->next = newNode;
// if p is the last node, make newNode as the last node
if (p == last) last = newNode;
return last;
}
p = p->next;
} while (p != last->next);
printf("\nThe given node is not present in the list");
return last;
}
// delete a node
void deleteNode(struct Node** last, int key) {
// if linked list is empty
if (*last == NULL) return;
// if the list contains only a single node
if ((*last)->data == key && (*last)->next == *last) {
free(*last);
*last = NULL;
return;
}
struct Node *temp = *last, *d;
// if last is to be deleted
if ((*last)->data == key) {
// find the node before the last node
while (temp->next != *last) temp = temp->next;
// point temp node to the next of last i.e. first node
temp->next = (*last)->next;
free(*last);
Information Technology

*last = temp->next;
}
// travel to the node to be deleted
while (temp->next != *last && temp->next->data != key) {
temp = temp->next;
}
// if node to be deleted was found
if (temp->next->data == key) {
d = temp->next;
temp->next = d->next;
free(d);
}
}
void traverse(struct Node* last) {
struct Node* p;
if (last == NULL) {
printf("The list is empty");
return;
}
p = last->next;
do {
printf("%d ", p->data);
p = p->next;
} while (p != last->next);
}
int main() {
struct Node* last = NULL;
last = addToEmpty(last, 6);
last = addEnd(last, 8);
last = addFront(last, 2);
last = addAfter(last, 10, 2);
traverse(last);
deleteNode(&last, 8);
printf("\n");
traverse(last);
return 0;
}
Output:
2 10 6 8
10 6 2
Information Technology

Exercise 5: Stack Operations

i) Implement a stack using arrays and linked lists.

Implementation of stack using arrays


include <stdio.h>
#define SIZE 10
int S[SIZE+1];
int top = 0;

int is_empty() {
if(top == 0)
return 1;
return 0;
}
void push(int x) {
top = top+1;
if(top > SIZE) {
printf("Stack Overflow\n");
}
else {
S[top] = x;
}
}
int pop() {
if(is_empty()) {
printf("Stack Underflow\n");
return -1000;
}
else {
top = top-1;
return S[top+1];
}
}
int main() {
pop();
push(10);
push(20);
push(30);
push(40);
push(50);
push(60);
push(70);
push(80);
push(90);
push(100);
push(110);
int i;
Information Technology

for(i=1; i<=SIZE; i++) {


printf("%d\n",S[i]);
}
return 0;
}
Output:
Stack Underflow
Stack Overflow
10
20
30
40
50
60
70
80
90
100

Implementation of stack using Linked Lists


#include <stdio.h>
#include <stdlib.h>
typedef struct node {
int data;
struct node *next;
}node;
typedef struct linked_list {
struct node *head;
struct node *top;
}stack;
//to make new node
node* new_node(int data) {
node *z;
z = malloc(sizeof(struct node));
z->data = data;
z->next = NULL;
return z;
}
//to make a new stack
stack* new_stack() {
stack *s = malloc(sizeof(stack));
s->head = NULL;
s->top = NULL;
return s;
}
void traversal(stack *s) {
node *temp = s->head; //temporary pointer to point to head
while(temp != NULL) { //iterating over stack
Information Technology

printf("%d\t", temp->data);
temp = temp->next;
}
printf("\n");
}
int is_empty(stack *s) {
if(s->top == NULL)
return 1;
return 0;
}
void push(stack *s, node *n) {
if(is_empty(s)) { //empty
s->head = n;
s->top = n;
}
else {
s->top->next = n;
s->top = n;
}
}
//function to delete
int pop(stack *s) {
if(is_empty(s)) {
printf("Stack Underflow\n");
return -1000;
}
else {
int x = s->top->data;
if(s->top == s->head) {// only one node
free(s->top);
s->top = NULL;
s->head = NULL;
}
else {
node *temp = s->head;
while(temp->next != s->top) // iterating to the last element
temp = temp->next;
temp->next = NULL;
free(s->top);
s->top = temp;
}
return x;
}
}
int main() {
stack *s = new_stack();
node *a, *b, *c;
a = new_node(10);
Information Technology

b = new_node(20);
c = new_node(30);
pop(s);
push(s, a);
push(s, b);
push(s, c);
traversal(s);
pop(s);
traversal(s);
return 0;
}
Output:
Stack Underflow
10 20 30
10 20
Information Technology

ii) Write a program to evaluate a postfix expression using a stack.


#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
struct Stack
{
int top;
unsigned size;
int* array;
};
struct Stack* createStack( unsigned size )
{
struct Stack* stack = (struct Stack*) malloc(sizeof(struct Stack));
if (!stack) return NULL;
stack->top = -1;
stack->size = size;
stack->array = (int*) malloc(stack->size * sizeof(int));
if (!stack->array) return NULL;

return stack;
}
int isEmpty(struct Stack* stack)
{
return stack->top == -1 ;
}
char peek(struct Stack* stack)
{
return stack->array[stack->top];
}
char pop(struct Stack* stack)
{
if (!isEmpty(stack))
return stack->array[stack->top--] ;
return '$';
}
void push(struct Stack* stack, char op)
{
stack->array[++stack->top] = op;
}
int evaluatePostfix(char* exp)
{
struct Stack* stack = createStack(strlen(exp));
int i;
if (!stack) return -1;
for (i = 0; exp[i]; ++i)
{
if (isdigit(exp[i]))
Information Technology

push(stack, exp[i] - '0');


else
{
int val1 = pop(stack);
int val2 = pop(stack);
switch (exp[i])
{
case '+': push(stack, val2 + val1); break;
case '-': push(stack, val2 - val1); break;
case '*': push(stack, val2 * val1); break;
case '/': push(stack, val2/val1); break;
}
}
}
return pop(stack);
}
int main()
{
char exp[20];
printf("Enter postfix expression : ");
gets(exp);
printf ("postfix evaluation: %d", evaluatePostfix(exp));
return 0;
}
Output:
Enter postfix expression: 35*
postfix evaluation: 15
Information Technology

iii) Implement a program to check for balanced parentheses using a stack.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
struct stack {
char stck[MAX];
int top;
}s;
void push(char item) {
if (s.top == (MAX - 1))
printf("Stack is Full\n");
else {
s.top = s.top + 1;
s.stck[s.top] = item;
}
}
void pop() {
if (s.top == -1)
printf("Stack is Empty\n");
else
s.top = s.top - 1;
}
int checkPair(char val1,char val2){
return (( val1=='(' && val2==')' )||( val1=='[' && val2==']' )||( val1=='{' && val2=='}' ));
}
int checkBalanced(char expr[], int len){

for (int i = 0; i < len; i++)


{
if (expr[i] == '(' || expr[i] == '[' || expr[i] == '{')
{
push(expr[i]);
}
else
{
// exp = {{}}}
// if you look closely above {{}} will be matched with pair, Thus, stack "Empty"
//but an extra closing parenthesis like '}' will never be matched
//so there is no point looking forward
if (s.top == -1)
return 0;
else if(checkPair(s.stck[s.top],expr[i]))
{
pop();
continue;
}
// will only come here if stack is not empty
Information Technology

// pair wasn't found and it's some closing parenthesis


//Example : {{}}(]
return 0;
}
}
return 1;
}
int main() {
char exp[MAX] = "({})[]{}";
int i = 0;
s.top = -1;
int len = strlen(exp);
checkBalanced(exp, len)?printf("…Balanced…"): printf("…Not Balanced…");
return 0;
}
Output:
…Balanced…
Information Technology

Exercise 6: Queue Operations

i) Implement a queue using arrays and linked lists.

Implementation of queue using arrays


#include<stdio.h>
#include<stdlib.h>
#define maxsize 5
void insert();
void delete();
void display();
int front = -1, rear = -1;
int queue[maxsize];
void main ()
{
int choice;
while(choice != 4)
{
printf(".........Menu......\n");
printf("-------------------------\n");
printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
printf(".....Enter your choice.....\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
insert();
break;
case 2:
delete();
break;
case 3:
display();
break;
case 4:
exit(0);
break;
default:
printf(".....Enter valid choice.....\n");
}
}
}
void insert()
{
int item;
printf("....Enter the element....\n");
scanf("\n%d",&item);
if(rear == maxsize-1)
Information Technology

{
printf("OVERFLOW\n");
return;
}
if(front == -1 && rear == -1)
{
front = 0;
rear = 0;
}
else
{
rear = rear+1;
}
queue[rear] = item;
printf("....Value inserted....\n");
}
void delete()
{
int item;
if (front == -1 || front > rear)
{
printf("UNDERFLOW\n");
return;
}
else
{
item = queue[front];
if(front == rear)
{
front = -1;
rear = -1 ;
}
else
{
front = front + 1;
}
printf("....value deleted....\n");
}
}
void display()
{
int i;
if(rear == -1)
{
printf("...Empty queue\n");
}
else
{ printf("....printing values .....\n");
Information Technology

for(i=front;i<=rear;i++)
{
printf("\n%d\n",queue[i]);
}
}
}
Output:
……Main Menu……
-----------------------------
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
……Enter your choice ….1
….Enter the element……
123
….Value inserted….
……Main Menu……
-----------------------------
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
……Enter your choice …..1
….Enter the element…..
90
….Value inserted…..

……Main Menu……
-----------------------------
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
….Enter your choice……2
….Value deleted….
….Enter your choice……3
....printing values .....
123
90
Information Technology

Implementation of queue using Linked Lists


#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node *next;
};
struct node *front;
struct node *rear;
void insert();
void delete();
void display();
void main ()
{
int choice;
while(choice != 4)
{
printf(".....Main Menu.......\n");
printf("------------------\n");
printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");
printf("......Enter your choice......");
scanf("%d",& choice);
switch(choice)
{
case 1:
insert();
break;
case 2:
delete();
break;
case 3:
display();
break;
case 4:
exit(0);
break;
default:
printf(".....Enter valid choice......\n");
}
}
}
void insert()
{
struct node *ptr;
int item;
ptr = (struct node *) malloc (sizeof(struct node));
if(ptr == NULL)
Information Technology

{
printf("\nOVERFLOW\n");
return;
}
else
{
printf(".....Enter value.....\n");
scanf("%d",&item);
ptr -> data = item;
if(front == NULL)
{
front = ptr;
rear = ptr;
front -> next = NULL;
rear -> next = NULL;
}
else
{
rear -> next = ptr;
rear = ptr;
rear->next = NULL;
}
}
}
void delete ()
{
struct node *ptr;
if(front == NULL)
{
printf("\nUNDERFLOW\n");
return;
}
else
{
ptr = front;
front = front -> next;
free(ptr);
}
}
void display()
{
struct node *ptr;
ptr = front;
if(front == NULL)
{
printf("\nEmpty queue\n");
}
else
Information Technology

{ printf(".......printing values .....\n");


while(ptr != NULL)
{
printf("\n%d\n",ptr -> data);
ptr = ptr -> next;
}
}
}
Output:
……Main Menu……
-----------------------------
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
……Enter your choice ….1
….Enter the element……
123
….Value inserted….
……Main Menu……
-----------------------------
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
……Enter your choice …..1
….Enter the element…..
90
….Value inserted…..

……Main Menu……
-----------------------------
1.insert an element
2.Delete an element
3.Display the queue
4.Exit
….Enter your choice……2
….Value deleted….
….Enter your choice……3
....printing values .....
123
90
Information Technology

ii) Develop a program to simulate a simple printer queue system.


#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
// Structure to represent a job in the queue
typedef struct Job {
int jobNumber;
struct Job *nextJob;
} Job;
// Structure to represent the printer queue
typedef struct {
Job *front;
Job *rear;
} PrinterQueue;
// Function to initialize the printer queue
void initQueue(PrinterQueue *queue) {
queue->front = NULL;
queue->rear = NULL;
}
// Function to check if the queue is empty
bool isEmpty(PrinterQueue *queue) {
return (queue->front == NULL);
}
// Function to enqueue a job into the printer queue
void enqueue(PrinterQueue *queue, int jobNumber) {
Job *newJob = (Job *)malloc(sizeof(Job));
if (newJob == NULL) {
fprintf(stderr, "Error: Memory allocation failed\n");
exit(1);
}
newJob->jobNumber = jobNumber;
newJob->nextJob = NULL;
if (isEmpty(queue)) {
queue->front = newJob;
queue->rear = newJob;
} else {
queue->rear->nextJob = newJob;
queue->rear = newJob;
}
}
// Function to dequeue a job from the printer queue
void dequeue(PrinterQueue *queue) {
if (isEmpty(queue)) {
fprintf(stderr, "Error: Queue is empty\n");
return;
}
Job *temp = queue->front;
queue->front = queue->front->nextJob;
Information Technology

free(temp);
if (queue->front == NULL) {
queue->rear = NULL;
}
}
// Function to display the contents of the printer queue
void displayQueue(PrinterQueue *queue) {
if (isEmpty(queue)) {
printf("Printer Queue is empty\n");
return;
}
Job *currentJob = queue->front;
printf("Printer Queue: ");
while (currentJob != NULL) {
printf("%d ", currentJob->jobNumber);
currentJob = currentJob->nextJob;
}
printf("\n");
}
int main() {
PrinterQueue printerQueue;
initQueue(&printerQueue);
// Enqueue some jobs
enqueue(&printerQueue, 1);
enqueue(&printerQueue, 2);
enqueue(&printerQueue, 3);
// Display the queue
displayQueue(&printerQueue);
// Dequeue a job
dequeue(&printerQueue);
// Display the updated queue
displayQueue(&printerQueue);
return 0;
}
Output:
Printer Queue: 1 2 3
Printer Queue: 2 3
Information Technology

i) Solve problems involving circular queues.


Circular queues are data structures that operate similarly to regular queues, but with the added
feature that once the queue is full and an element is dequeued, the newly available space can be
reused, effectively creating a circular behavior. Here's an example C program to implement a
circular queue and solve problems involving it:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define MAX_SIZE 5
// Structure to represent a circular queue
typedef struct {
int items[MAX_SIZE];
int front, rear;
} CircularQueue;
// Function to initialize the circular queue
void initCircularQueue(CircularQueue *queue) {
queue->front = -1;
queue->rear = -1;
}
// Function to check if the circular queue is empty
bool isEmpty(CircularQueue *queue) {
return (queue->front == -1);
}
// Function to check if the circular queue is full
bool isFull(CircularQueue *queue) {
return ((queue->rear + 1) % MAX_SIZE == queue->front);
}
// Function to enqueue an element into the circular queue
void enqueue(CircularQueue *queue, int value) {
if (isFull(queue)) {
fprintf(stderr, "Error: Queue is full\n");
return;
}
if (isEmpty(queue)) {
queue->front = 0;
}
queue->rear = (queue->rear + 1) % MAX_SIZE;
queue->items[queue->rear] = value;
printf("Enqueued: %d\n", value);
}
// Function to dequeue an element from the circular queue
int dequeue(CircularQueue *queue) {
if (isEmpty(queue)) {
fprintf(stderr, "Error: Queue is empty\n");
exit(1);
}
int value = queue->items[queue->front];
if (queue->front == queue->rear) {
Information Technology

queue->front = -1;
queue->rear = -1;
} else {
queue->front = (queue->front + 1) % MAX_SIZE;
}
return value;
}
// Function to display the elements in the circular queue
void displayQueue(CircularQueue *queue) {
if (isEmpty(queue)) {
printf("Circular Queue is empty\n");
return;
}
printf("Circular Queue: ");
int i = queue->front;
do {
printf("%d ", queue->items[i]);
i = (i + 1) % MAX_SIZE;
} while (i != (queue->rear + 1) % MAX_SIZE);
printf("\n");
}
int main() {
CircularQueue circularQueue;
initCircularQueue(&circularQueue);
// Enqueue elements into the circular queue
enqueue(&circularQueue, 1);
enqueue(&circularQueue, 2);
enqueue(&circularQueue, 3);
enqueue(&circularQueue, 4);
enqueue(&circularQueue, 5);
displayQueue(&circularQueue);
// Dequeue elements from the circular queue
printf("Dequeued: %d\n", dequeue(&circularQueue));
printf("Dequeued: %d\n", dequeue(&circularQueue));
displayQueue(&circularQueue);
// Enqueue another element after dequeue
enqueue(&circularQueue, 6);
displayQueue(&circularQueue);
return 0;
}
Output:
Enqueued: 6
Circular Queue: 3 4 5 6
Information Technology

Exercise 7: Stack and Queue Applications

i) Use a stack to evaluate an infix expression and convert it to postfix.


#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX 20
char stk[20];
int top = -1;
int isEmpty(){
return top == -1;
}
int isFull(){
return top == MAX - 1;
}
char peek(){
return stk[top];
}
char pop(){
if(isEmpty())
return -1;
char ch = stk[top];
top--;
return(ch);
}
void push(char oper){
if(isFull())
printf("Stack Full!!!!");
else{
top++;
stk[top] = oper;
}
}
int checkIfOperand(char ch)
{
return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z');
}
int precedence(char ch)
{
switch (ch)
{
case '+':
case '-':
return 1;
case '*':
case '/':
return 2;
case '^':
Information Technology

return 3;
}
return -1;
}
int covertInfixToPostfix(char* expression)
{
int i, j;
for (i = 0, j = -1; expression[i]; ++i)
{
if (checkIfOperand(expression[i]))
expression[++j] = expression[i];
else if (expression[i] == '(')
push(expression[i]);
else if (expression[i] == ')')
{
while (!isEmpty() && peek() != '(')
expression[++j] = pop();
if (!isEmpty() && peek() != '(')
return -1; // invalid expression
else
pop();
}
else // if an opertor
{
while (!isEmpty() && precedence(expression[i]) <= precedence(peek()))
expression[++j] = pop();
push(expression[i]);
}
}
while (!isEmpty())
expression[++j] = pop();
expression[++j] = '\0';
printf( "%s", expression);
}
int main()
{
char expression[] = "((p+(q*r))-s)";
covertInfixToPostfix(expression);
return 0;
}
Output:
pqr*+s-
Information Technology

ii) Create a program to determine whether a given string is a palindrome or not.


#include <stdio.h>
#include <stdlib.h>
int main() {
// str is the string to be cheked for palindrome
char str[] = "cabbac";
int l = sizeof(str);
char rev[l + 1];
int i = l - 2;
// while loop to reverse the string
while (i >= 0) {
rev[l - i - 2] = str[i];
i--;
}
// compare the initial string and reversed string
int res = 0;
if (res == 0) {
printf("%s is a Palindrome\n", str);
} else {
printf("%s is not a Palindrome\n", str);
}
}
Output:
cabbac is a Palindrome
Information Technology

iii) Implement a stack or queue to perform comparison and check for symmetry.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <ctype.h>
// Structure to represent a stack node
typedef struct StackNode {
char data;
struct StackNode *next;
} StackNode;
// Structure to represent a stack
typedef struct {
StackNode *top;
} Stack;
// Function to initialize the stack
void initStack(Stack *stack) {
stack->top = NULL;
}
// Function to check if the stack is empty
bool isEmpty(Stack *stack) {
return (stack->top == NULL);
}
// Function to push an element onto the stack
void push(Stack *stack, char data) {
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
if (newNode == NULL) {
fprintf(stderr, "Error: Memory allocation failed\n");
exit(1);
}
newNode->data = data;
newNode->next = stack->top;
stack->top = newNode;
}
// Function to pop an element from the stack
char pop(Stack *stack) {
if (isEmpty(stack)) {
fprintf(stderr, "Error: Stack is empty\n");
exit(1);
}
StackNode *temp = stack->top;
char poppedData = temp->data;
stack->top = temp->next;
free(temp);
return poppedData;
}
// Function to perform symmetry check on a string
bool isSymmetric(char *str) {
Stack stack;
Information Technology

initStack(&stack);
// Push alphanumeric characters onto the stack
for (int i = 0; str[i] != '\0'; i++) {
if (isalnum(str[i])) {
push(&stack, tolower(str[i]));
}
}
// Compare characters from the stack with the remaining characters in the string
for (int i = 0; str[i] != '\0'; i++) {
if (isalnum(str[i])) {
char stackChar = pop(&stack);
if (tolower(str[i]) != stackChar) {
return false; // Not symmetric
}
}
}
return isEmpty(&stack); // Stack should be empty if symmetric
}
int main() {
char inputString[100];
printf("Enter a string to check for symmetry: ");
fgets(inputString, sizeof(inputString), stdin);
// Remove newline character from input
inputString[strcspn(inputString, "\n")] = '\0';
if (isSymmetric(inputString)) {
printf("The string is symmetric.\n");
} else {
printf("The string is not symmetric.\n");
}
return 0;
}
Output:
Enter a string to check for symmetry: gghgg
The string is symmetric.
Information Technology

Exercise 8: Binary Search Tree

i) Implementing a BST using Linked List.


#include <stdio.h>
#include <stdlib.h>
struct node {
int data;
struct node *right_child;
struct node *left_child;
};
struct node* new_node(int x){
struct node *temp;
temp = malloc(sizeof(struct node));
temp->data = x;
temp->left_child = NULL;
temp->right_child = NULL;
return temp;
}
struct node* search(struct node * root, int x){
if (root == NULL || root->data == x)
return root;
else if (x > root->data)
return search(root->right_child, x);
else
return search(root->left_child, x);
}
struct node* insert(struct node * root, int x){
if (root == NULL)
return new_node(x);
else if (x > root->data)
root->right_child = insert(root->right_child, x);
else
root -> left_child = insert(root->left_child, x);
return root;
}
struct node* find_minimum(struct node * root) {
if (root == NULL)
return NULL;
else if (root->left_child != NULL)
return find_minimum(root->left_child);
return root;
}
struct node* delete(struct node * root, int x) {
if (root == NULL)
return NULL;
if (x > root->data)
root->right_child = delete(root->right_child, x);
else if (x < root->data)
Information Technology

root->left_child = delete(root->left_child, x);


else {
if (root->left_child == NULL && root->right_child == NULL){
free(root);
return NULL;
}
else if (root->left_child == NULL || root->right_child == NULL){
struct node *temp;
if (root->left_child == NULL)
temp = root->right_child;
else
temp = root->left_child;
free(root);
return temp;
}
else {
struct node *temp = find_minimum(root->right_child);
root->data = temp->data;
root->right_child = delete(root->right_child, temp->data);
}
}
return root;
}
void inorder(struct node *root){
if (root != NULL)
{
inorder(root->left_child);
printf(" %d ", root->data);
inorder(root->right_child);
}
}
int main() {
struct node *root;
root = new_node(20);
insert(root, 5);
insert(root, 1);
insert(root, 15);
insert(root, 9);
insert(root, 7);
insert(root, 12);
insert(root, 30);
insert(root, 25);
insert(root, 40);
insert(root, 45);
insert(root, 42);
inorder(root);
printf("\n");
root = delete(root, 1);
Information Technology

root = delete(root, 40);


root = delete(root, 45);
root = delete(root, 9);
inorder(root);
printf("\n");
return 0;
}
Output:
1 5 7 9 12 15 20 25 30 40 42 45
5 7 12 15 20 25 30 42
Information Technology

ii. Traversing of BST.

#include <stdio.h>
#include <stdlib.h>
// Structure for a node in the BST
typedef struct TreeNode {
int key;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
// Function to create a new node with the given key
TreeNode* createNode(int key) {
TreeNode* newNode = (TreeNode*)malloc(sizeof(TreeNode));
if (newNode == NULL) {
fprintf(stderr, "Error: Memory allocation failed\n");
exit(1);
}
newNode->key = key;
newNode->left = NULL;
newNode->right = NULL;
return newNode;
}
// Function to insert a key into the BST
TreeNode* insert(TreeNode* root, int key) {
if (root == NULL) {
return createNode(key);
}
if (key < root->key) {
root->left = insert(root->left, key);
} else if (key > root->key) {
root->right = insert(root->right, key);
}
return root;
}
// Inorder Traversal: Visit left subtree, current node, then right subtree
void inorderTraversal(TreeNode* root) {
if (root != NULL) {
inorderTraversal(root->left);
printf("%d ", root->key);
inorderTraversal(root->right);
}
}
// Preorder Traversal: Visit current node, left subtree, then right subtree
void preorderTraversal(TreeNode* root) {
if (root != NULL) {
printf("%d ", root->key);
preorderTraversal(root->left);
preorderTraversal(root->right);
Information Technology

}
}
// Postorder Traversal: Visit left subtree, right subtree, then current node
void postorderTraversal(TreeNode* root) {
if (root != NULL) {
postorderTraversal(root->left);
postorderTraversal(root->right);
printf("%d ", root->key);
}
}
int main() {
TreeNode* root = NULL;
// Insert keys into the BST
root = insert(root, 50);
root = insert(root, 30);
root = insert(root, 20);
root = insert(root, 40);
root = insert(root, 70);
root = insert(root, 60);
root = insert(root, 80);
// Perform inorder traversal (ascending order)
printf("Inorder traversal (ascending order): ");
inorderTraversal(root);
printf("\n");
// Perform preorder traversal
printf("Preorder traversal: ");
preorderTraversal(root);
printf("\n");
// Perform postorder traversal
printf("Postorder traversal: ");
postorderTraversal(root);
printf("\n");
return 0;
}
Output:
Inorder traversal (ascending order): 20 30 40 50 60 70 80
Preorder traversal: 50 30 20 40 70 60 80
Postorder traversal: 20 40 30 60 80 70 50
Information Technology

Exercise 9: Hashing
i) Implement a hash table with collision resolution techniques.
Chaining
#include<stdio.h>
#include<stdlib.h>
#define size 7
struct node
{
int data;
struct node *next;
};
struct node *chain[size];
void init()
{
int i;
for(i = 0; i < size; i++)
chain[i] = NULL;
}
void insert(int value)
{
//create a newnode with value
struct node *newNode = malloc(sizeof(struct node));
newNode->data = value;
newNode->next = NULL;
//calculate hash key
int key = value % size;
//check if chain[key] is empty
if(chain[key] == NULL)
chain[key] = newNode;
//collision
else
{
//add the node at the end of chain[key].
struct node *temp = chain[key];
while(temp->next)
{
temp = temp->next;
}
temp->next = newNode;
}
}
void print()
{
int i;

for(i = 0; i < size; i++)


{
struct node *temp = chain[i];
Information Technology

printf("chain[%d]-->",i);
while(temp)
{
printf("%d -->",temp->data);
temp = temp->next;
}
printf("NULL\n");
}
}
int main()
{
//init array of list to NULL
init();
insert(7);
insert(0);
insert(3);
insert(10);
insert(4);
insert(5);
print();
return 0;
}
Output:
chain[0]-->7 -->0 -->NULL
chain[1]-->NULL
chain[2]-->NULL
chain[3]-->3 -->10 -->NULL
chain[4]-->4 -->NULL
chain[5]-->5 -->NULL
chain[6]-->NULL
Information Technology

Open Addressing
#include <stdio.h>
#include <conio.h>
void display(int a[], int n)
{
int i;
// Displaying complete hash table
for (i = 0; i < n; i++)
{
printf("\n %d %d",i,a[i]);
}
}
void Linear_prob(int table[], int tsize,int num)
{
int key = num % tsize; //Computing the hash key using hash function
while (table[key]!= -1) //if empty slot is not found
{
key=(key+1)%tsize; //then move linearly dow in search of empty slot
}
table[key]=num ; //if empty slot gets then insert the element
display(table, tsize);
}
int main()
{
int SIZE = 10;// Size of the hash table
int num;
int hash_table[10];
char ans;
int i;
// Initializing the hash table
for (i=0; i < SIZE; i++)
{
hash_table[i] -1;//-1 indicates empty slot
}
do
{
printf("\nEnter The Number: ");
scanf("%d", &num); //This element is to be inserted in hash table
Linear_prob(hash_table,SIZE,num);
printf("\n Do U Wish To Continue?(y/n)");
ans = getch();
} while(ans=='y');
return 0;
}
Output
Enter The Number: 131
0 -1
1 131
Information Technology

2 -1
3 -1
4 -1
5 -1
6 -1
7 -1
8 -1
9 -1
Do U Wish To Continue?(y/n)
Enter The Number: 21
0 -1
1 131
2 21
3 -1
4 -1
5 -1
6 -1
7 -1
8 -1
9 -1
Do U Wish To Continue? (y/n)
Enter The Number: 3
0 -1
1 131
2 21
33
4 -1
5 -1
6 -1
7 -1
8 -1
9 -1
Do U Wish To Continue? (y/n)
Enter The Number: 4
0 -1
1 131
2 21
33
44
5 -1
6 -1
7 -1
8 -1
9 -1
Do U Wish To Continue?(y/n)
Enter The Number: 5
0 -1
1 131
Information Technology

2 21
33
44
55
6 -1
7 -1
8 -1
9 -1
Do U Wish To Continue?(y/n)
Enter The Number: 8
0 -1
1 131
2 21
33
44
55
6 -1
7 -1
88
9 -1
Do U Wish To Continue?(y/n)
Enter The Number: 9
0 -1
1 131
2 21
33
44
55
6 -1
7 -1
88
99
Do U Wish To Continue?(y/n)
Enter The Number: 18
0 18
1 131
2 21
33
44
55
6 -1
7 -1
88
99
Do U Wish To Continue?(y/n)
Enter The Number: 33
0 18
1 131
Information Technology

2 21
33
44
55
6 33
7 -1
88
99
Information Technology

ii. Write a program to implement a simple cache using hashing

// A C program to show implementation of LRU cache


#include <stdio.h>
#include <stdlib.h>
// A Queue Node (Queue is implemented using Doubly Linked// List)
typedef struct QNode {
struct QNode *prev, *next;
unsigned
pageNumber; // the page number stored in this QNode
} QNode;
// A Queue (A FIFO collection of Queue Nodes)
typedef struct Queue {
unsigned count; // Number of filled frames
unsigned numberOfFrames; // total number of frames
QNode *front, *rear;
} Queue;
// A hash (Collection of pointers to Queue Nodes)
typedef struct Hash {
int capacity; // how many pages can be there
QNode** array; // an array of queue nodes
} Hash;
// A utility function to create a new Queue Node. The queue
// Node will store the given 'pageNumber'
QNode* newQNode(unsigned pageNumber)
{
// Allocate memory and assign 'pageNumber'
QNode* temp = (QNode*)malloc(sizeof(QNode));
temp->pageNumber = pageNumber;

// Initialize prev and next as NULL


temp->prev = temp->next = NULL;

return temp;
}
// A utility function to create an empty Queue.
// The queue can have at most 'numberOfFrames' nodes
Queue* createQueue(int numberOfFrames)
{
Queue* queue = (Queue*)malloc(sizeof(Queue));
// The queue is empty
queue->count = 0;
queue->front = queue->rear = NULL;
// Number of frames that can be stored in memory
queue->numberOfFrames = numberOfFrames;
return queue;
}
// A utility function to create an empty Hash of given
Information Technology

// capacity
Hash* createHash(int capacity)
{
// Allocate memory for hash
Hash* hash = (Hash*)malloc(sizeof(Hash));
hash->capacity = capacity;
// Create an array of pointers for referring queue nodes
hash->array
= (QNode**)malloc(hash->capacity * sizeof(QNode*));
// Initialize all hash entries as empty
int i;
for (i = 0; i < hash->capacity; ++i)
hash->array[i] = NULL;
return hash;
}
// A function to check if there is slot available in memory
int AreAllFramesFull(Queue* queue)
{
return queue->count == queue->numberOfFrames;
}
// A utility function to check if queue is empty
int isQueueEmpty(Queue* queue)
{
return queue->rear == NULL;
}
// A utility function to delete a frame from queue
void deQueue(Queue* queue)
{
if (isQueueEmpty(queue))
return;
// If this is the only node in list, then change front
if (queue->front == queue->rear)
queue->front = NULL;
// Change rear and remove the previous rear
QNode* temp = queue->rear;
queue->rear = queue->rear->prev;
if (queue->rear)
queue->rear->next = NULL;
free(temp);
// decrement the number of full frames by 1
queue->count--;
}
// A function to add a page with given 'pageNumber' to both
// queue and hash
void Enqueue(Queue* queue, Hash* hash, unsigned pageNumber)
{
// If all frames are full, remove the page at the rear
if (AreAllFramesFull(queue)) {
Information Technology

// remove page from hash


hash->array[queue->rear->pageNumber] = NULL;
deQueue(queue);
}
// Create a new node with given page number,
// And add the new node to the front of queue
QNode* temp = newQNode(pageNumber);
temp->next = queue->front;
// If queue is empty, change both front and rear
// pointers
if (isQueueEmpty(queue))
queue->rear = queue->front = temp;
else // Else change the front
{
queue->front->prev = temp;
queue->front = temp;
}
// Add page entry to hash also
hash->array[pageNumber] = temp;
// increment number of full frames
queue->count++;
}
void ReferencePage(Queue* queue, Hash* hash,
unsigned pageNumber)
{
QNode* reqPage = hash->array[pageNumber];
// the page is not in cache, bring it
if (reqPage == NULL)
Enqueue(queue, hash, pageNumber);
// page is there and not at front, change pointer
else if (reqPage != queue->front) {
// Unlink rquested page from its current location
// in queue.
reqPage->prev->next = reqPage->next;
if (reqPage->next)
reqPage->next->prev = reqPage->prev;
// If the requested page is rear, then change rear
// as this node will be moved to front
if (reqPage == queue->rear) {
queue->rear = reqPage->prev;
queue->rear->next = NULL;
}
// Put the requested page before current front
reqPage->next = queue->front;
reqPage->prev = NULL;
// Change prev of current front
reqPage->next->prev = reqPage;
// Change front to the requested page
Information Technology

queue->front = reqPage;
}
}
// Driver code
int main()
{
// Let cache can hold 4 pages
Queue* q = createQueue(4);
// Let 10 different pages can be requested (pages to be
// referenced are numbered from 0 to 9
Hash* hash = createHash(10);
// Let us refer pages 1, 2, 3, 1, 4, 5
ReferencePage(q, hash, 1);
ReferencePage(q, hash, 2);
ReferencePage(q, hash, 3);
ReferencePage(q, hash, 1);
ReferencePage(q, hash, 4);
ReferencePage(q, hash, 5);
// Let us print cache frames after the above referenced
// pages
printf("%d ", q->front->pageNumber);
printf("%d ", q->front->next->pageNumber);
printf("%d ", q->front->next->next->pageNumber);
printf("%d ", q->front->next->next->next->pageNumber);
return 0;
}
Output:
5413

You might also like