0% found this document useful (0 votes)
34 views

DS Lab Manual (With Code)

The document discusses finding the minimum and maximum elements in an array. It provides the algorithm to initialize two variables - min and max with the first element of the array, then traverse the array and compare each element with min and max to update their values if a smaller element is found for min or larger for max.

Uploaded by

Sivasai Charitha
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
34 views

DS Lab Manual (With Code)

The document discusses finding the minimum and maximum elements in an array. It provides the algorithm to initialize two variables - min and max with the first element of the array, then traverse the array and compare each element with min and max to update their values if a smaller element is found for min or larger for max.

Uploaded by

Sivasai Charitha
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 126

INDEX

S. No Name of the Experiment


1
Array Operations
2 Maximum and minimum elements in an array
3 Reverse an array
4 Insert an element at begin and delete at end in Singly Linked List.
5 Reverse the Singly linked list
6 Double ended queue using linked list – inject, eject and display operations.
7 Doubly linked list implementation and its operations
8 Circular linked list implementation and its operations
9 Stack using arrays.
10 Evaluation of a postfix expression using a stack
11 Check for balanced parentheses using a stack
12 Queue using linked lists
13 Circular Queue using arrays
14 Converting an infix expression to postfix
15 Determine whether a given string is a palindrome or not using a stack.
16 Graph traversal using BFS
17 Graph traversal using DFS
18 Linear probing
19 Binary tree traversals using linked list with recursion
20 Topological sorting on a graph

1. Write a Program to implement basic operations on arrays: insertion, deletion and


searching.
Problem statement:
To implement basic operations on arrays: insertion, deletion and searching.
Description:
The basic operations in the Arrays are insertion, deletion, searching, display,
traverse, and update. These operations are usually performed to either modify the data in
the array or to report the status of the array.

Insertion: Insertion in an array is the process of including one or more elements in an


array.

Deletion: In this array operation, we delete an element from the particular index of an array.
This deletion operation takes place as we assign the value in the consequent index to the
current index.

Searching: Searching an element in the array using a key. The key element sequentially
compares every value in the array to check if the key is present in the array or not.

Algorithm for Insertion:

1. Start
2. Create an Array of a desired datatype and size.
3. Initialize a variable 'i' as 0.
4. Enter the element at ith index of the array.
5. Increment i by 1.
6. Repeat Steps 4 & 5 until the end of the array.
7. Stop

Algorithm for Deletion:


Consider LA is a linear array with N elements and K is a positive integer such that K<=N.
Following is the algorithm to delete an element available at the K th position of LA.
1. Start
2. Set J = K
3. Repeat steps 4 and 5 while J < N
4. Set LA[J] = LA[J + 1]
5. Set J = J+1
6. Set N = N-1
7. Stop
Algorithm for Searching:
Consider LA is a linear array with N elements and K is a positive integer such that K<=N.
Following is the algorithm to find an element with a value of ITEM using sequential search.
1. Start
2. Set J = 0
3. Repeat steps 4 and 5 while J < N
4. IF LA[J] is equal ITEM THEN GOTO STEP 6
5. Set J = J +1
6. PRINT J, ITEM
7. Stop
Tracing:
Insertion:
• Consider an example with n=5 and array elements as 2, 7, 1, 23, 5.
• Now ask the user for x and pos. Suppose the value entered by user are x=15 and pos=4.
• Increment the value of n by 1 i.e., n=6. Run a for loop from i=n-1 = 5 to i=pos = 4 and
in each iteration insert the element at previous index i.e., i-1 to index i. Therefore,
array[5] = array[4] which is equal to 5.
• Decrement the value of i by 1 and repeat the same process array[4] = array[3] i.e.,
array[4] = 23.
• Now i=3 and pos=4 so condition in for loop becomes false, come out of the loop.
• Now, insert the element x in index pos-1 i.e., array[3] = 15.
• The element is inserted now, run a for loop and print the array with element being
inserted. i.e. 2 7 1 15 23 5

Deletion:
To delete a specific element from an array, a user must define the position from which the
array's element should be removed. The deletion of the element does not affect the size of an
array. Furthermore, we should also check whether the deletion is possible or not in an array.

Searching: To understand the working of linear search algorithm, let's take an unsorted array.
It will be easy to understand the working of linear search with an example.

• Let the elements of array are –

Let the element to be searched is K = 41

• Now, start from the first element and compare K with each element of the array.

The value of K, i.e., 41, is not matched with the first element of the array. So, move
to the next element. And follow the same process until the respective element is
found.
• Now, the element to be searched is found. So algorithm will return the index of the
element matched.

Source Code

#include<stdio.h>
#include<stdlib.h>
int a[20];
int n, p, i , pos, val;
void create();
void display();
void insert();
void del();
void search();
int main() {
int choice;
do{
printf("1.Create\n");
printf("2.Display\n");
printf("3.Insert\n");
printf("4.Delete\n");
printf("5.Exit\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice) {
case 1:
create();
break;
case 2:
display();
break;
case 3:
insert();
break;
case 4:
del();
break;
case 5:
exit(0);
break;
default:
printf("Invalid choice. Enter valid input.\n");
break;
}
}while(choice!=5);
return 0;
}

void create() {
printf("Enter the size of the array elements : ");
scanf("%d",&n);
printf("Enter the elements for the array : ");
for(i=0;i<n;i++) {
scanf("%d",&a[i]);
}

void display() {
printf("The array elements are : ");
for(i=0;i<n;i++) {
printf("%d ",a[i]);
}
printf("\n");

void insert() {
printf("Enter the position(index) for the new element : ");
scanf("%d",&pos);
printf("Enter the element to be inserted : ");
scanf("%d",&val);
if(pos < 0 || pos > n) {
printf("Invalid position.\n");
} else {
for(i=n-1;i>=pos;i--) {
a[i+1]=a[i];
}
a[pos]=val;
n=n+1;
}
}

void del() {
printf("Enter the position(index) of the element to be deleted : ");
scanf("%d",&pos);
if( pos < 0 || pos >= n) {
printf("Invalid position.\n");
} else {
val=a[pos];
for(i=pos;i<n-1;i++) {
a[i]=a[i+1];
}
n=n-1;
printf("The deleted element is : %d\n",val);
}

Output:
1.Create⏎
2.Display⏎
3.Insert⏎
4.Delete⏎
5.Exit⏎
Enter·your·choice·:·1
Enter·the·size·of·the·array·elements·:·5
Enter·the·elements·for·the·array·:·1 2 3 4 5
1.Create⏎
2.Display⏎
3.Insert⏎
4.Delete⏎
5.Exit⏎
Enter·your·choice·:·2
The·array·elements·are·:·1·2·3·4·5·⏎
1.Create⏎
2.Display⏎
3.Insert⏎
4.Delete⏎
5.Exit⏎
Enter·your·choice·:·3
Enter·the·position(index)·for·the·new·element·:·3
Enter·the·element·to·be·inserted·:·8
1.Create⏎
2.Display⏎
3.Insert⏎
4.Delete⏎
5.Exit⏎
Enter·your·choice·:·2
The·array·elements·are·:·1·2·3·8·4·5·⏎
1.Create⏎
2.Display⏎
3.Insert⏎
4.Delete⏎
5.Exit⏎
Enter·your·choice·:·4
Enter·the·position(index)·of·the·element·to·be·deleted·:·3
The·deleted·element·is·:·8⏎
1.Create⏎
2.Display⏎
3.Insert⏎
4.Delete⏎
5.Exit⏎
Enter·your·choice·:·5
2. Write a program to find minimum and maximum elements in an array.

Problem statement:
To find minimum and maximum elements in an array.
Description :
In this program to input elements in an array from user, find maximum and minimum
element in array. Initially we consider the array’s first element to be both maximum and
minimum value. As and when we traverse the array, we compare the value of the elements in
the array with that of current value of ‘max’ or ‘min’ and respectively assign the values if the
current value is not maximum for ‘max’ and not minimum for ‘min’.

Algorithm :
Step 1 : Take the size of an array from a user and stored it in variable n.
Step 2 : Take n element from the user and store it in an array .
Step 3 : We initialize two variables min and max with arr[0],to store the maximum and
minimum.
Step 4: Now we traverse the array from 1=1 to n-1 and compare each element with min and
max.
Step 5 : Start loop at 1, using index i. Check if arr[i] < min; if so, set min to arr[i] Check if
arr[i] > max; if so, set max to arr[i]
• If(arr[i]<min):we have found a value arr[i] smaller than the minimum so far.so we
update min with arr[i].i.e min=arr[i].
• If(arr[i]>max):We have found a value arr[i] greater than the maximum so far.so ,we
update max with arr[i],i.e max=arr[i].
Step 6 : At end of loop, the minimum and maximum values of the array will be stored in the
variables min and max.

Tracing :

Maximum :

1.max=a[0]=53 for(i=1;1<7;i++) if(max<a[1]) i.e :53<32.(Fail)


2.max=a[0]=53 for(i=2;2<7;i++) if(max<a[2]) i.e :53<19.(Fail)
3. max=a[0]=53 for(i=3;3<7;i++) if(max<a[3]) i.e :53<79.(True)
4. max=a[3]=79 for(i=4;4<7;i++) if(max<a[4]) i.e :79<25.(Fail)
5.max=a[3]=79 for(i=5;5<7;i++) if(max<a[5]) i.e :79<5.(Fail)
6.max=a[3]=79 for(i=6;6<7;i++) if(max<a[6]) i.e :79<47.(Fail)
7.max=a[3]=79 finally loop also teriminated.

Minimum :

1.min=a[0]=53 for(i=1;1<7;i++) if(min>a[1]) i.e :53>32.(True)


2.min=a[1]=32 for(i=2;2<7;i++) if(min>a[2]) i.e :32>19.(True)
3.min=a[2]=19 for(i=3;3<7;i++) if(min>a[3]) i.e :19>79.(Fail)
4. .min=a[2]=19 for(i=4;4<7;i++) if(min>a[4]) i.e :19>25.(Fail)
5. .min=a[2]=19 for(i=5;5<7;i++) if(min>a[5]) i.e :19>5.(True)
6. .min=a[5]=5 for(i=6;6<7;i++) if(min>a[6]) i.e :5>47.(Fail)
7. .min=a[5]=5 finally loop also terminated.

Source Code:
#include <stdio.h>

int main() {
int numbers[100], numCount, i;
int largest = -2147483648, smallest = 2147483647; // initialize to min and max values of
int

scanf("%d", &numCount);

for (i = 0; i < numCount; i++) {


scanf("%d", &numbers[i]);

if (numbers[i] > largest) {


largest = numbers[i];
}
if (numbers[i] < smallest) {
smallest = numbers[i];
}
}
printf("Maximum element is %d\n", largest);
printf("Minimum element is %d\n", smallest);

return 0;
}
Output:
5
52 63 45 12 90
Maximum·element·is·90⏎
Minimum·element·is·12⏎

3. Write a C program to reverse an array.


Problem statement:
Implement to reverse an array.
Description :
In this program we have an array with n elements. We shall have to reverse the elements
present in the array and display them. In C, there are no inbuilt functions to reverse an array,
we have to write the code for it on our own. An array can be reversed using different methods
and algorithms - printing it from the last element, using an auxiliary array, recursion, swapping,
etc. So, if the input is like n = 6 arr = [9, 8, 7, 2, 4, 3], then the output will be [3,4,2,7,8,9].

Algorithm :

1. Firstly, input the size n and the elements of the array arr.
2. Initialize an auxiliary array rarr of size same as the array arr.
3. Run a for loop with an integer i=0, where i<0 and i increments by 1 in each iteration.
4. Inside the for loop, assign rarr[i] to be arr[n−i−1].
5. Then copy the elements of the array arr into the array rarr .
6. Print the array rarr

Tracing :
For example, Suppose given an array:

We need to reverse the array and print the following:

In this array, size of array n=6


Here we use loop for(i=0;i<n;i++)
rarr[i]=arr[n-i-1]
1.for(i=0;0<6;i++) (T) rarr[0]=arr[6-0-1]=arr[5]=6.
2.for(i=1;1<6;i++) (T) rarr[1]=arr[6-1-1]=arr[4]=5.
3.for(i=2;2<6;i++) (T) rarr[2]=arr[6-2-1]=arr[3]=4.
4.for(i=3;3<6;i++) (T) rarr[3]=arr[6-3-1]=arr[2]=3.
5.for(i=4;4<6;i++) (T) rarr[4]=arr[6-4-1]=arr[1]=2.
6.for(i=5;5<6;i++) (T) rarr[5]=arr[6-5-1]=arr[0]=1
7. for(i=6;6<6;i++) (F) condition failed loop will be terminated.

Source Code:

#include <stdio.h>
#include <stdlib.h>
int main()
{ int num, *arr, i;
scanf("%d", &num);
arr = (int*) malloc(num * sizeof(int));
for(i = 0; i < num; i++) {
scanf("%d", arr + i);
}
// logic to reverse the array
int* left_ptr = arr;
int* right_ptr;
int temp;
for(i = 0; i < num; i++) {
if(i == num - 1) {
right_ptr = (arr + i);
}
}
while(left_ptr < right_ptr) {
temp = *right_ptr;
*right_ptr = *left_ptr;
*left_ptr = temp;
right_ptr--;
left_ptr++;
}

for(i = 0; i < num; i++) {


printf("%d ", *(arr + i));
}
free(arr);
return 0;
}
Output:
3
15 24 62
62·24·15·

4. Write a C program to insert an element at begin and delete at end in Singly Linked
List.

Problem statement:
To insert an element at begin and delete at end in Singly Linked List.
Description:
Given a linked list, the task is to insert a new node at the beginning/start/front of the
linked list.

Algorithm for Insertion:

• Step 1: IF pointer = NULL Then Go to step 7 that is exit otherwise follow step2
[END OF IF]
• Step 2: SET New_Node = pointer
• Step 3: SET pointer = pointer → next
• Step 4: SET New_Node → data= value
• Step 5: SET New_Node →next =head
• Step 6: SET head = New_Node
• Step 7: Exit

Tracing:

Algorithm for Deletion:

There are two scenarios in which, a node is deleted from the end of the linked list.
1. There is only one node in the list and that needs to be deleted.
2. There are more than one node in the list and the last node of the list will be deleted.

In the first scenario,


The condition head → next = NULL will survive and therefore, the only node head of
the list will be assigned to null. This will be done by using the following statements.
The condition head → next = NULL would fail and therefore, we have to traverse the
node in order to reach the last node of the list.
For this purpose, just declare a temporary pointer temp and assign it to head of the list. We
also need to keep track of the second last node of the list. For this purpose, two pointers ptr and
ptr1 will be used where ptr will point to the last node and ptr1 will point to the second last node
of the list.

• Step 1:IF HEAD = NULL Write UNDERFLOW Go to Step 8 [END OF IF]


• Step 2: SET PTR = HEAD
• Step 3: Repeat Steps 4 and 5 while PTR -> NEXT!= NULL
• Step 4: SET PREPTR = PTR
• Step 5:SET PTR = PTR -> NEXT [END OF LOOP]
• Step 6: SET PREPTR -> NEXT = NULL
• Step 7: FREE PTR
• Step 8: EXIT

When list has only one node, which is indicated by the condition, that the head points to
the same node as the tail, the removal is quite simple. Algorithm disposes the node, pointed
by head (or tail) and sets both head and tail to NULL.

Second case: This operation is a bit more tricky, than removing the first node, because
algorithm should find a node, which is previous to the tail first.

It can be done in three steps:


1. Update tail link to point to the node, before the tail. In order to find it, list should be
traversed first, beginning from the head.

2. Set next link of the new tail to NULL.


3. Dispose removed node.

Source Code (a):


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

#include "InsAtBeginAndDelEnd.c"

void main() {
NODE first = NULL;
int x, op;
while(1) {
printf("1.Insert At Begin 2.Delete at End 3.Traverse the List 4.Exit\n");
printf("Enter your option : ");
scanf("%d", &op);
switch(op) {
case 1: printf("Enter an element : ");
scanf("%d", &x);
first = insertAtBegin(first, x);
break;
case 2:if (first == NULL) {
printf("Single Linked List is empty so deletion
is not possible\n");
} else {
first = deleteAtEnd(first);
}
break;
case 3: if (first == NULL) {
printf("Single Linked List is empty\n");
} else {
printf("The elements in SLL are : ");
traverseList(first);
}
break;
case 4: exit(0);
}
}
}
InsAtBeginAndDelEnd
struct node {
int data;
struct node *next;
};
typedef struct node *NODE;

NODE createNode() {
NODE temp;
temp = (NODE) malloc(sizeof(struct node));
temp -> next = NULL;
return temp;
}

NODE insertAtBegin(NODE first, int x) {


NODE temp;
temp = createNode();
temp -> data = x;
temp -> next = first;
first = temp;
return first;
}
NODE deleteAtEnd(NODE first) {
NODE prev, lastNode = first;
if (lastNode -> next == NULL) {
first = first -> next;
} else {
while (lastNode -> next != NULL) {
prev = lastNode;
lastNode = lastNode -> next;
}
prev -> next = NULL;
}
printf("The deleted item from SLL : %d\n", lastNode -> data);
free(lastNode);
return first;
}
void traverseList(NODE first) {
NODE temp = first;
while (temp != NULL) {
printf("%d --> ",temp -> data);
temp = temp -> next;
}
printf("NULL\n");
}
Output:
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎
Enter·your·option·:·1
Enter·an·element·:·15
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎
Enter·your·option·:·1
Enter·an·element·:·49
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎
Enter·your·option·:·1
Enter·an·element·:·26
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎
Enter·your·option·:·3
The·elements·in·SLL·are·:·26·-->·49·-->·15·-->·NULL⏎
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎
Enter·your·option·:·2
The·deleted·item·from·SLL·:·15⏎
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎
Enter·your·option·:·3
The·elements·in·SLL·are·:·26·-->·49·-->·NULL⏎
1.Insert·At·Begin·2.Delete·at·End·3.Traverse·the·List·4.Exit⏎

5.Write a program to reverse the Singly Linked List.

Problem statement: To reverse a SLL.


Description:
To reversing a singly linked list requires an additional data structure to temporarily
store the values. We can use a stack for this. By pushing each node onto the stack as we move
through the list, we effectively reverse the order of the nodes.

Algorithm:
Begin:
If (head != NULL) then
prevNode ← head
head ← head.next
curNode ← head
prevNode.next ← NULL
While (head != NULL) do
head ← head.next
curNode.next ← prevNode
prevNode ← curNode
curNode ← head
End while
head ← prevNode
End if
End

Tracing:

1. Create two more pointers other than head namely prevNode and curNode that will hold
the reference of previous node and current node respectively.
Make sure that prevNode points to first node i.e. prevNode = head.
head should now point to its next node i.e. the second node head = head->next.
curNode should also points to the second node i.e. curNode = head.

2. Now, disconnect the previous node i.e. the first node from others. We will make sure
that it points to none. As this node is going to be our last node. Perform operation
prevNode→next=NULL
3. Move head node to its next node i.e. head = head->next.

4. Now, re-connect the current node to its previous node i.e. curNode->next = prevNode;

5. Point the previous node to current node and current node to head node. Means they
should now point to prevNode = curNode; and curNode = head.

6. Repeat steps 3-5 till head pointer becomes NULL.


7. Now, after all nodes has been re-connected in the reverse order. Make the last node as
the first node. Means the head pointer should point to prevNode pointer. Perform head
= prevNode;. Finally you end up with a reversed linked list of its original.

Source Code:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct node {
int data;
struct node *next;
}*head;
void createList(int n);
void reverseList();
void displayList();

void createList(int n) {
struct node *newNode, *temp;
int data, i;
head = (struct node *)malloc(sizeof(struct node));
if(head == NULL) {
printf("Unable to allocate memory.");
}
else {
scanf("%d", &data);
head->data = data; // Link the data field with data
head->next = NULL; // Link the address field to NULL
temp = head;
for(i=2; i<=n; i++) {
newNode = (struct node *)malloc(sizeof(struct node));
/* If memory is not allocated for newNode */
if(newNode == NULL) {
printf("Unable to allocate memory.");
break;
}
else {
scanf("%d", &data);
newNode->data = data; // Link the data field of newNode with data
newNode->next = NULL; // Link the address field of newNode with NULL
temp->next = newNode; // Link previous node i.e. temp to the newNode
temp = temp->next;
}
}
}
}
void reverseList() {
struct node *prevNode, *curNode;
if(head != NULL) {
prevNode = head;
curNode = head->next;
head = head->next;
prevNode->next = NULL; // Make first node as last node
while(head != NULL) {
head = head->next;
curNode->next = prevNode;
prevNode = curNode;
curNode = head;
}
head = prevNode; // Make last node as head
}
}
void displayList() {
struct node *temp;
if(head == NULL) {
printf("List is empty.");
}
else {
temp = head;
while(temp != NULL) {
printf("%d ", temp->data); // Print the data of current node
temp = temp->next;
}
}
}
void check(int n){
int x;
printf("Enter no.of nodes: ");
scanf("%d", &n);
if (n>0){
while (true){
printf("Enter data: ");
createList(n);
reverseList();
printf("Reversed the list: ");
displayList();
break;
}
}
else {
printf("List size must be greater than zero:\n");
check(n);
}
}
void main(){
int n;
check(n);
}

Output:

Enter·no.of·nodes:·4
Enter·data:·1 2 3 4
Reversed·the·list:·4·3·2·1·
6. Implementation of double ended queue using linked list – inject, eject and display
operations.

Problem statement: To implement a Double Ended Queue using linked list.


Description:
Deque or Double Ended Queue is a generalized version of Queue data structure that
allows insert and delete at both ends. In previous post Implementation of Deque using circular
array has been discussed. Now in this post we see how we implement Deque using Doubly
Linked List.

Operations on Deque :
Mainly the following four basic operations are performed on queue :

insertFront() : Adds an item at the front of Deque.


insertRear() : Adds an item at the rear of Deque.
deleteFront() : Deletes an item from front of Deque.
deleteRear() : Deletes an item from rear of Deque.

Algorithm for Insertion at Front end :

1. Allocate space for a newNode of doubly linked list.


2. IF newNode == NULL, then
3. print "Overflow"
4. ELSE
5. IF front == NULL, then
6. rear = front = newNode
7. ELSE
8. newNode->next = front
9. front->prev = newNode
10. front = newNode

Example:
Algorithm for Insertion at Rear end :

1. Allocate space for a newNode of doubly linked list.


2. IF newNode == NULL, then
3. print "Overflow"
4. ELSE
5. IF rear == NULL, then
6. front = rear = newNode
7. ELSE
8. newNode->prev = rear
9. rear->next = newNode
10. rear = newNode

Example:

Algorithm for Deletion from Front end :

1. IF front == NULL
2. print "Underflow"
3. ELSE
4. Initialize temp = front
5. front = front->next
6. IF front == NULL
7. rear = NULL
8. ELSE
9. front->prev = NULL
10 Deallocate space for temp

Example:

Algorithm for Deletion from Rear end :

1. IF front == NULL
2. print "Underflow"
3. ELSE
4. Initialize temp = rear
5. rear = rear->prev
6. IF rear == NULL
7. front = NULL
8. ELSE
9. rear->next = NULL
10 Deallocate space for temp

Example:

Source Code (a):

#include <stdio.h>
#include <stdlib.h>
#include "DequeueListInjectEject.c"
int main() {
int op, x;
while (1) {
printf("1.Inject 2.Eject 3.Display 4.Exit\n");
printf("Enter your option : ");
scanf("%d", & op);
switch (op) {
case 1:
printf("Enter element : ");
scanf("%d", & x);
inject(x);
break;
case 2:
eject();
break;
case 3:
display();
break;
case 4:
exit(0);
}
}
}
DequeueListInjectEject
struct queue {
int data;
struct queue *next;
};
typedef struct queue *DeQueue;
DeQueue front = NULL, rear = NULL;

void inject(int ele) {


DeQueue temp = NULL;
temp = (DeQueue)malloc(sizeof(struct queue));
if(temp == NULL) {
printf("Dequeue is overflow.\n");
} else {
temp -> data = ele;
temp -> next = NULL;
if(front == NULL) {
front = temp;
} else {
rear -> next = temp;
}
rear = temp;
printf("Successfully inserted at rear side.\n");
}
}
void eject() {DeQueue temp = NULL;
if(rear == NULL) {
printf("Dequeue is underflow.\n");
} else {
temp = front;
if (front == rear) {
front = rear = NULL;
} else {
while(temp -> next != rear) {
temp = temp -> next;
}
rear=temp;
temp = rear -> next;
rear->next = NULL;
}
printf("Deleted element %d from the rear side.\n", temp -> data);
free(temp);
}
}
void display() {
if(front == NULL) {
printf("Double ended queue is empty.\n");
} else {
DeQueue temp = front;
printf("Elements in the double ended queue : \n");
while(temp != NULL) {
printf("%d ", temp -> data);
temp = temp -> next;
}
printf("\n");
}
}
Output:

1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·1
Enter·element·:·12
Successfully·inserted·at·rear·side.⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·1
Enter·element·:·13
Successfully·inserted·at·rear·side.⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·1
Enter·element·:·14
Successfully·inserted·at·rear·side.⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·3
Elements·in·the·double·ended·queue·:·⏎
12·13·14·⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·2
Deleted·element·14·from·the·rear·side.⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·12
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·3
Elements·in·the·double·ended·queue·:·⏎
12·13·⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·2
Deleted·element·13·from·the·rear·side.⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·3
Elements·in·the·double·ended·queue·:·⏎
12·⏎
1.Inject·2.Eject·3.Display·4.Exit⏎
Enter·your·option·:·4
7.Implement a doubly linked list and perform various operations to understand its
properties and applications.

Problem statement: To implement doubly linked list.


Description: A Doubly Linked List in contains three parts: one is the data part and the other
two are the address of the next and previous node in the list.

We can insert elements at 3 different positions of a doubly-linked list:

1. Insertion at the beginning


2. Insertion in-between nodes
3. Insertion at the End

Suppose we have a double-linked list with elements 1, 2, and 3.

1. Insertion

Adding a node to a doubly linked list is similar to adding a node to a linked list. The only
extra work is to handle the pointer to the previous node. It is faster than linked lists because we
just need to change the pointers of adjacent elements of the element we are inserting.

Generalized Algorithm for Insertion in a Doubly Linked List


Step 1: Create a new node with the given data.
Step 2: If the doubly linked list is empty:
i. Set the head and tail pointers point to the new node.
ii. make the new node's prev and next pointers point to NULL.
Step 3: If the doubly linked list is not empty:
i. Perform the insertion as per your requirement, either in the beginning, end, or at a given
position.
I. Insertion at the Beginning
Let's add a node with value 6 at the beginning of the doubly linked list we made above.

1. Create a new node

• allocate memory for newNode


• assign the data to newNode.
New node
2. Set prev and next pointers of new node
• point next of newNode to the first node of the doubly linked list
• point prev to null

Reorganize the pointers (changes are denoted by purple arrows)


3. Make new node as head node

• Point prev of the first node to newNode (now the previous head is the second node)
• Point head to newNod

Reorganize the pointers

II. Insertion in between two nodes


Let's add a node with value 6 after node with value 1 in the doubly linked list.

1. Create a new node

• allocate memory for newNode


• assign the data to newNode.

New node
2. Set the next pointer of new node and previous node

• assign the value of next from previous node to the next of newNode
• assign the address of newNode to the next of previous node

Reorganize the pointers

3. Set the prev pointer of new node and the next node

• assign the value of prev of next node to the prev of newNode


• assign the address of newNode to the prev of next node

Reorganize the pointers

The final doubly linked list is after this insertion is:

Final list
III. Insertion at the End
Let's add a node with value 6 at the end of the doubly linked list.

1. Create a new node

New node
2. Set prev and next pointers of new node and the previous node

If the linked list is empty, make the newNode as the head node. Otherwise, traverse to
the end of the doubly linked list and

Reorganize the pointers

The final doubly linked list looks like this.

The final list

Deletion from a Doubly Linked List

Similar to insertion, we can also delete a node from 3 different positions of a doubly linked
list.
Original doubly linked list

1.Delete the First Node of Doubly Linked List

If the node to be deleted (i.e. del_node) is at the beginning


Reset value node after the del_node (i.e. node two)

Reorganize the pointers

Finally, free the memory of del_node. And, the linked will look like this
Final list

2. Deletion of the Inner Node

If del_node is an inner node (second node), we must have to reset the value of next and prev
of the nodes before and after the del_node.

For the node before the del_node (i.e. first node)

Assign the value of next of del_node to the next of the first node.

For the node after the del_node (i.e. third node)

Assign the value of prev of del_node to the prev of the third node.

Reorganize the pointers

Finally, we will free the memory of del_node. And, the final doubly linked list looks like this.

Final list

3. Delete the Last Node of Doubly Linked List


In this case, we are deleting the last node with value 3 of the doubly linked list.
Here, we can simply delete the del_node and make the next of node before del_node point to
NULL.
Reorganize the pointers

The final doubly linked list looks like this.

Final list

3.Traversal

We can traverse the doubly linked list in both directions. We can go to the previous
node by following the previous pointers and similarly go to the next nodes by following the
next pointers to perform some specific operations like searching, sorting, display, etc.

Algorithm for Traversing a Doubly Linked List

Step 1. Set a pointer current to the head of the doubly linked list.
Step 2. If the doubly linked list is empty (i.e., current is null), then the traversal is complete.
Step 3. While the current pointer is not null:
a. Process the data of the current node.
b. Move the current pointer to the next node (current = current->next).
or
b. Move the 'current' pointer to the previous node (current = current->prev)
Step 4. The traversal is complete when the 'current' pointer becomes null.

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

struct node
{ char ssn[25], name[25], dept[10], designation[25];
int sal;
long long int phone;
struct node *llink;
struct node *rlink;
};

typedef struct node* NODE;


NODE first = NULL;
int count = 0;

NODE create()
{ NODE enode;
enode = (NODE)malloc(sizeof(struct node));
if( enode == NULL)
{ printf("Running out of memory");
exit(0);
}
printf("Enter ssn, Name, Department, Designation, Salary, PhoneNo of employee: ");
scanf("%s %s %s %s %d %lld", enode->ssn, enode->name, enode->dept, enode-
>designation, &enode->sal, &enode->phone);
enode->llink = NULL;
enode->rlink = NULL;
count++;
return enode;
}

NODE insertfront()
{ NODE temp;
temp = create();
if(first == NULL)
{ return temp; }
temp->rlink = first;
first->llink = temp;
return temp;
}

void display()
{ NODE cur;
int nodeno=1;
cur = first;
if(cur == NULL)
printf("DLL is Empty\n");
else{
while(cur != NULL)
{ printf("SSN:%s| Name:%s| Department:%s| Designation:%s| Salary:%d|
Phone no:%lld", cur->ssn, cur->name,cur->dept, cur->designation, cur->sal, cur->phone);
cur = cur->rlink;
nodeno++;
printf("\n");
}
printf("No of employees: %d\n",count);
}
}

NODE deletefront()
{ NODE temp;
if(first == NULL)
{ printf("DLL is empty\n");
return NULL;
}
if(first->rlink == NULL)
{ printf("employee with ssn: %s is deleted\n", first->ssn);
free(first);
count--;
return NULL;
}
temp = first;
first = first->rlink;
temp->rlink = NULL;
first->llink = NULL;
printf("employee with ssn: %s is deleted\n",temp->ssn);
free(temp);
count--;
return first;
}

NODE insertend()
{ NODE cur, temp;
temp = create();
if(first == NULL)
{ return temp; }
cur = first;
while(cur->rlink != NULL)
{ cur = cur->rlink; }
cur->rlink = temp;
temp->llink = cur;
return first;
}

NODE deleteend()
{ NODE prev,cur;
if(first == NULL)
{ printf("DLL is empty\n");
return NULL;
}
if(first->rlink == NULL)
{ printf("employee with ssn: %s is deleted\n",first->ssn);
free(first);
count--;
return NULL;
}
prev=NULL;
cur=first;
while(cur->rlink!=NULL)
{ prev=cur;
cur = cur->rlink;
}
cur->llink = NULL;
printf("employee with ssn: %s is deleted\n",cur->ssn);
free(cur);
prev->rlink = NULL;
count--;
return first;
}

void main()
{ int ch,i,n;
while(1){
printf("1: Create DLL of Employee Nodes");
printf("\n2: DisplayStatus");
printf("\n3: InsertAtEnd");
printf("\n4: DeleteAtEnd");
printf("\n5: InsertAtFront");
printf("\n6: DeleteAtFront");
printf("\n7: Exit");
printf("\nPlease enter your choice: ");
scanf("%d",&ch);
switch(ch)
{ case 1 : printf("Enter no of Employees: ");
scanf("%d",&n);
for(i=1;i<=n;i++)
first = insertend();
break;
case 2 : display();
break;
case 3 : first = insertend();
break;
case 4 : first = deleteend();
break;
case 5 : first = insertfront();
break;
case 6 : first = deletefront();
break;
case 7 : exit(0);
default: printf("Please Enter valid choice\n");
}
}
}

Output:
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
DLL·is·Empty⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·1
Enter·no·of·Employees:·2
Enter·ssn,·Name,·Department,·Designation,·Salary,·PhoneNo·of·employee:·CT156 Hema Support
PSE 30000 1234567890
Enter·ssn,·Name,·Department,·Designation,·Salary,·PhoneNo·of·employee:·CT188 Prasanth
Support PSE 30000 1234567890
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:CT156|·Name:Hema|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:1234567
890⏎
SSN:CT188|·Name:Prasanth|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:12345
67890⏎
No·of·employees:·2⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·3
Enter·ssn,·Name,·Department,·Designation,·Salary,·PhoneNo·of·employee:·CT226 Swathi Support
PSE 30000 1234567890
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:CT156|·Name:Hema|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:1234567
890⏎
SSN:CT188|·Name:Prasanth|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:12345
67890⏎
SSN:CT226|·Name:Swathi|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:123456
7890⏎
No·of·employees:·3⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·4
employee·with·ssn:·CT226·is·deleted⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:CT156|·Name:Hema|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:1234567
890⏎
SSN:CT188|·Name:Prasanth|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:12345
67890⏎
No·of·employees:·2⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·5
Enter·ssn,·Name,·Department,·Designation,·Salary,·PhoneNo·of·employee:·CT156 Bhanu Support
PSE 34000 1234567890
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:CT156|·Name:Bhanu|·Department:Support|·Designation:PSE|·Salary:34000|·Phone·no:123456
7890⏎
SSN:CT156|·Name:Hema|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:1234567
890⏎
SSN:CT188|·Name:Prasanth|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:12345
67890⏎
No·of·employees:·3⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:CT156|·Name:Bhanu|·Department:Support|·Designation:PSE|·Salary:34000|·Phone·no:123456
7890⏎
SSN:CT156|·Name:Hema|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:1234567
890⏎
SSN:CT188|·Name:Prasanth|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:12345
67890⏎
No·of·employees:·3⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·6
employee·with·ssn:·CT156·is·deleted⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·4
employee·with·ssn:·CT188·is·deleted⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:CT156|·Name:Hema|·Department:Support|·Designation:PSE|·Salary:30000|·Phone·no:1234567
890⏎
No·of·employees:·1⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·6
employee·with·ssn:·CT156·is·deleted⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
DLL·is·Empty⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·4
DLL·is·empty⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·6
DLL·is·empty⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·3
Enter·ssn,·Name,·Department,·Designation,·Salary,·PhoneNo·of·employee:·198 Tanjiro Anime
Hero 49000 1029384756
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·2
SSN:198|·Name:Tanjiro|·Department:Anime|·Designation:Hero|·Salary:49000|·Phone·no:102938475
6⏎
No·of·employees:·1⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·4
employee·with·ssn:·198·is·deleted⏎
1:·Create·DLL·of·Employee·Nodes⏎
2:·DisplayStatus⏎
3:·InsertAtEnd⏎
4:·DeleteAtEnd⏎
5:·InsertAtFront⏎
6:·DeleteAtFront⏎
7:·Exit⏎
Please·enter·your·choice:·7
8.Implement a circular linked list and perform insertion, deletion, and traversal.

Problem statement: To implement a circular linked list and perform insertion, deletion, and
traversal.

Description: The circular linked list is a linked list where all nodes are connected to form a
circle. In a circular linked list, the first node and the last node are connected to each other which
forms a circle. There is no NULL at the end.

Operations on Circular Linked List

1. Insertion operation
2. Deletion operation
3. Traversal operation

Insertion Operation

Operation Description
Insertion at beginning Inserts the element at the beginning of the linked list
Insertion at end Insert the element at the end of the list
Insertion after certain node Insert element after specific element

Deletion Operation

Operation Description
Deletion at beginning delete the element from the beginning of the linked list
Deletion at end delete the element from the end of the list
Deletion after specific node delete element after specific element
Traversal Operation
Operation Description
Traversal Visiting every node in a list at least once
Inserting At Beginning of the list
We can use the following steps to insert a new node at beginning of the circular linked list...

• Step 1 - Create a newNode with given value.


• Step 2 - Check whether list is Empty (head == NULL)
• Step 3 - If it is Empty then, set head = newNode and newNode→next = head .
• Step 4 - If it is Not Empty then, define a Node pointer 'temp' and initialize with
'head'.
• Step 5 - Keep moving the 'temp' to its next node until it reaches to the last node (until
'temp → next == head').
• Step 6 - Set 'newNode → next =head', 'head = newNode' and 'temp → next = head'.
Before Insertion

After Insertion

Inserting At End of the list

We can use the following steps to insert a new node at end of the circular linked list...

• Step 1 - Create a newNode with given value.


• Step 2 - Check whether list is Empty (head == NULL).
• Step 3 - If it is Empty then, set head = newNode and newNode → next = head.
• Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
• Step 5 - Keep moving the temp to its next node until it reaches to the last node in the
list (until temp → next == head).
• Step 6 - Set temp → next = newNode and newNode → next = head.

Before Insertion
After Insertion

Inserting At Specific location in the list (After a Node)

We can use the following steps to insert a new node after a node in the circular linked list...

• Step 1 - Create a newNode with given value.


• Step 2 - Check whether list is Empty (head == NULL)
• Step 3 - If it is Empty then, set head = newNode and newNode → next = head.
• Step 4 - If it is Not Empty then, define a node pointer temp and initialize with head.
• Step 5 - Keep moving the temp to its next node until it reaches to the node after
which we want to insert the newNode (until temp1 → data is equal to location, here
location is the node value after which we want to insert the newNode).
• Step 6 - Every time check whether temp is reached to the last node or not. If it is
reached to last node then display 'Given node is not found in the list!!! Insertion
not possible!!!' and terminate the function. Otherwise move the temp to next node.
• Step 7 - If temp is reached to the exact node after which we want to insert the
newNode then check whether it is last node (temp → next == head).
• Step 8 - If temp is last node then set temp → next = newNode and newNode → next
= head.
• Step 8 - If temp is not last node then set newNode → next = temp → next and temp
→ next = newNode.
Deleting from Beginning of the list

We can use the following steps to delete a node from beginning of the circular linked list...

• Step 1 - Check whether list is Empty (head == NULL)


• Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminate the function.
• Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize both 'temp1' and 'temp2' with head.
• Step 4 - Check whether list is having only one node (temp1 → next == head)
• Step 5 - If it is TRUE then set head = NULL and delete temp1 (Setting Empty list
conditions)
• Step 6 - If it is FALSE move the temp1 until it reaches to the last node. (until temp1
→ next == head )
• Step 7 - Then set head = temp2 → next, temp1 → next = head and delete temp2.

Deleting from End of the list

We can use the following steps to delete a node from end of the circular linked list...

• Step 1 - Check whether list is Empty (head == NULL)


• Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminate the function.
• Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize 'temp1' with head.
• Step 4 - Check whether list has only one Node (temp1 → next == head)
• Step 5 - If it is TRUE. Then, set head = NULL and delete temp1. And terminate
from the function. (Setting Empty list condition)
• Step 6 - If it is FALSE. Then, set 'temp2 = temp1 ' and move temp1 to its next node.
Repeat the same until temp1 reaches to the last node in the list. (until temp1 → next
== head)
• Step 7 - Set temp2 → next = head and delete temp1.

Deleting a Specific Node from the list

We can use the following steps to delete a specific node from the circular linked list...
• Step 1 - Check whether list is Empty (head == NULL)
• Step 2 - If it is Empty then, display 'List is Empty!!! Deletion is not possible' and
terminate the function.
• Step 3 - If it is Not Empty then, define two Node pointers 'temp1' and 'temp2' and
initialize 'temp1' with head.
• Step 4 - Keep moving the temp1 until it reaches to the exact node to be deleted or to
the last node. And every time set 'temp2 = temp1' before moving the 'temp1' to its
next node.
• Step 5 - If it is reached to the last node then display 'Given node not found in the
list! Deletion not possible!!!'. And terminate the function.
• Step 6 - If it is reached to the exact node which we want to delete, then check whether
list is having only one node (temp1 → next == head)
• Step 7 - If list has only one node and that is the node to be deleted then set head =
NULL and delete temp1 (free(temp1)).
• Step 8 - If list contains multiple nodes then check whether temp1 is the first node in
the list (temp1 == head).
• Step 9 - If temp1 is the first node then set temp2 = head and keep moving temp2 to
its next node until temp2 reaches to the last node. Then set head = head → next,
temp2 → next = head and delete temp1.
• Step 10 - If temp1 is not first node then check whether it is last node in the list
(temp1 → next == head).
• Step 1 1- If temp1 is last node then set temp2 → next = head and delete temp1
(free(temp1)).
• Step 12 - If temp1 is not first node and not last node then set temp2 → next = temp1
→ next and delete temp1 (free(temp1)).

Displaying a circular Linked List

We can use the following steps to display the elements of a circular linked list...

• Step 1 - Check whether list is Empty (head == NULL)


• Step 2 - If it is Empty, then display 'List is Empty!!!' and terminate the function.
• Step 3 - If it is Not Empty then, define a Node pointer 'temp' and initialize with
head.
• Step 4 - Keep displaying temp → data with an arrow (--->) until temp reaches to the
last node
• Step 5 - Finally display temp → data with arrow pointing to head → data.
Sourcecode :

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

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

NODE createNodeInCLL() {
NODE temp;
temp = (NODE) malloc(sizeof(struct node));
temp -> next = NULL;
return temp;
}

NODE insertAtPositionInCLL(NODE first, int pos, int x) {


NODE temp, lastNode = first;
int i ;
for (i = 1; i < (pos - 1); i++) {
if (lastNode -> next == first) {
printf("No such position in CLL so insertion is not possible\n");
return first;
}
lastNode = lastNode -> next;
}
temp = createNodeInCLL();
temp -> data = x;
if (pos == 1) {
if (first == NULL) {
first = temp;
temp -> next = first;
} else {
while (lastNode -> next != first) {
lastNode = lastNode -> next;
}
temp -> next = first;
first = temp;
lastNode -> next = first;
}
} else {
temp -> next = lastNode -> next;
lastNode -> next = temp;
}
return first;
}

NODE deleteAtPositionInCLL(NODE first, int pos) {


NODE prev = first, lastNode = first;
int i;
if (pos == 1) {
if (prev -> next == first) {
first = NULL;
} else {
while (lastNode -> next != first) {
lastNode = lastNode -> next;
}
first = prev -> next;
lastNode -> next = first;
}
} else {
for (i = 1; i < pos; i++) {
if (prev -> next == first) {
printf("No such position in CLL so deletion is not possible\n");
return first;
}
lastNode = prev;
prev = prev -> next;
}
lastNode -> next = prev -> next;
}
printf("The deleted element from CLL : %d\n", prev -> data);
free(prev);
return first;
}

void traverseListInCLL(NODE first) {


NODE temp = first;
do {
printf("%d --> ", temp -> data);
temp = temp -> next;
} while (temp != first);
printf("\n");
}

void main() {
NODE first = NULL;
int x, pos, op;
while(1) {
printf("1.Insert 2.Delete 3.Print 4.Exit\n");
printf("Enter your option: ");
scanf("%d", &op);
switch(op) {
case 1: printf("Enter a position: ");
scanf("%d", &pos);
if (pos <= 0) {
printf("No such position in CLL so insertion is
not possible\n");
} else {
printf("Enter an element: ");
scanf("%d", &x);
first = insertAtPositionInCLL(first, pos, x);
}
break;
case 2: if (first == NULL) {
printf("Circular Linked List is empty so deletion
is not possible\n");
} else {
printf("Enter position : ");
scanf("%d", &pos);
first = deleteAtPositionInCLL(first, pos);
}
break;
case 3: if (first == NULL) {
printf("Circular Linked List is empty\n");
} else {
printf("The elements in CLL are: ");
traverseListInCLL(first);
}
break;
case 4: exit(0);
}
}
}

Output:
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·1
Enter·an·element:·1
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·2
Enter·an·element:·2
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·3
Enter·an·element:·3
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·4
Enter·an·element:·4
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·5
Enter·an·element:·5
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·6
Enter·an·element:·6
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·3
The·elements·in·CLL·are:·1·-->·2·-->·3·-->·4·-->·5·-->·6·-->·⏎
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·2
Enter·position·:·3
The·deleted·element·from·CLL·:·3⏎
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·2
Enter·position·:·3
The·deleted·element·from·CLL·:·4⏎
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·2
Enter·position·:·3
The·deleted·element·from·CLL·:·5⏎
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·3
The·elements·in·CLL·are:·1·-->·2·-->·6·-->·⏎
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·3
Enter·an·element:·3
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·4
Enter·an·element:·4
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·1
Enter·a·position:·5
Enter·an·element:·5
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·3
The·elements·in·CLL·are:·1·-->·2·-->·3·-->·4·-->·5·-->·6·-->·⏎
1.Insert·2.Delete·3.Print·4.Exit⏎
Enter·your·option:·4
9.Implement a stack using arrays.

Problem statement: To Implement a stack using arrays.

Description: The stack is a linear data structure following the last-in-first-out (LIFO) order,
meaning the most recently added element is the first to be removed. This tutorial will
implement a basic stack in C using an array. We will cover the two primary operations
performed on a stack: pushing an element (adding to the stack) and popping an element
(removing from the stack).

Algorithm for PUSH() operation in Stack using Array:


Step 1: Start

Step 2: Declare Stack[MAX]; //Maximum size of Stack

Step 3: Check if the stack is full or not by comparing top with (MAX-1)
If the stack is full, Then print "Stack Overflow" i.e, stack is full and cannot
be pushed with another element

Step 4: Else, the stack is not full


Increment top by 1 and Set, a[top] = x
which pushes the element x into the address pointed by top.
// The element x is stored in a[top]

Step 5: Stop

Algorithm for POP() operation in Stack using Array:


Step 1: Start

Step 2: Declare Stack[MAX]

Step 3: Push the elements into the stack

Step 4: Check if the stack is empty or not by comparing top with base of array i.e 0
If top is less than 0, then stack is empty, print "Stack Underflow"

Step 5: Else, If top is greater than zero the stack is not empty, then store the value pointed by
top in a variable x=a[top] and decrement top by 1. The popped element is x.
Example:

Source code ( a) :

#include <stdio.h>
#include <stdlib.h>
#define STACK_MAX_SIZE 10
#include "StackOperations.c"

int main() {
int op, x;
while(1) {
printf("1.Push 2.Pop 3.Display 4.Is Empty 5.Peek 6.Exit\n");
printf("Option: ");
scanf("%d", &op);
switch(op) {
case 1:
printf("element: ");
scanf("%d", &x);
push(x);
break;
case 2:
pop();
break;
case 3:
display();
break;
case 4:
isEmpty();
break;
case 5:
peek();
break;
case 6:
exit(0);
}
}
}

StackOperations
int arr[STACK_MAX_SIZE];// declare the size of the array
int top = -1;// define the top to -1

void push(int element) {


if(top == STACK_MAX_SIZE - 1) {
printf("Stack is overflow\n");
} else {
top = top + 1;
arr[top] = element;
printf("Successfully pushed\n");
}

}
void display() {
if (top < 0) {
printf("Stack is empty\n");
} else {
printf("Elements: ");
for(int i = top; i >= 0; i--) {
printf("%d ", arr[i]);
}
printf("\n");
}

}
void pop() {
int x;
if(top < 0) {
printf("Stack is underflow\n");
} else {
x = arr[top];
top = top - 1;
printf("Popped value: %d\n",x);
}

}
void peek(){
int x;
if(top < 0) {
printf("Stack is underflow\n");
} else {
x = arr[top];
printf("Peek value: %d\n",x);
}

}
void isEmpty() {
if (top < 0) {
printf("Stack is empty\n");
} else {
printf("Stack is not empty\n");
}
}

Output:

1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·4
Stack·is·empty⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·2
Stack·is·underflow⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·3
Stack·is·empty⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·5
Stack·is·underflow⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·1
element:·25
Successfully·pushed⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·1
element:·26
Successfully·pushed⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·3
Elements:·26·25·⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·2
Popped·value:·26⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·4
Stack·is·not·empty⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·5
Peek·value:·25⏎
1.Push·2.Pop·3.Display·4.Is·Empty·5.Peek·6.Exit⏎
Option:·6
10.Write a program to evaluate a postfix expression using a stack.

Problem statement: To evaluate a postfix expression using a stack.


Description: Iterate the expression from left to right and keep on storing the operands into a
stack. Once an operator is received, pop the two topmost elements and evaluate them and push
the result in the stack again.

Algorithm for Evaluation of Postfix Expression

1. Add ) to postfix expression.


2. Read postfix expression Left to Right until ) encountered
3. If operand is encountered, push it onto Stack
[End If]
4. If operator is encountered, Pop two elements
1. A -> Top element
2. B-> Next to Top element
3. Evaluate B operator A
4. Push B operator A onto Stack
5. Set result = pop
6. END

Example for Evaluation of Postfix Expression


Let's see an example to better understand the algorithm:
Expression: 456*+
Source code:

#include <ctype.h>
#include <stdio.h>
#define STACK_MAX_SIZE 20
int stack [STACK_MAX_SIZE];
int top = -1;

//Return 1 if stack is empty else return 0.


int isEmpty() {
if(top<0)
return 1;
else
return 0;
}

//Push the character into stack


void push(int x) {
if(top == STACK_MAX_SIZE - 1) {
printf("Stack is overflow.\n");
} else {
top = top + 1;
stack[top] = x;
}
}
//pop a character from stack
int pop() {
if(top < 0) {
return -1;
}
else
return stack[top--];
}

//Output Format - Result : <result> if the input postfix expression is vaild.


//Output Format - Invalid postfix expression,. - if the input expression is invalid.
//postfix expression is given as the parameter.
void evaluatePostfix(char * e) {
int a,b,result;
while(*e != '\0') {
if(isdigit(*e))
push(*e-'0');
else if (*e == '+' || *e == '-' || *e == '*' || *e == '/' || *e == '%'){
if(isEmpty()){
printf("Invalid postfix expression.\n");
return;
}
a = pop();
if(isEmpty()){
printf("Invalid postfix expression.\n");
return;
}
b = pop();
switch(*e) {
case '+':
result = b + a;
break;
case '-':
result = b - a;
break;
case '*':
result = b * a;
break;
case '/':
result = b / a;
break;
case '%':
result = b % a;
break;
}
push(result);
}
e++;
}
if(isEmpty()){
printf("Invalid postfix expression.\n");
return;
}
result = pop();
if(!isEmpty()) {
printf("Invalid postfix expression.\n");
return;
}
printf("Result : %d\n",result);
}

//Read a postfix expression and evaluate it.


int main() {
char exp[20];
char *e, x;
printf("Enter the postfix expression : ");
scanf("%s",exp);
e = exp;
evaluatePostfix(e);
}
/*#include <ctype.h>
#include <stdio.h>
#define STACK_MAX_SIZE 20
//Declare the required stack variables.

//Return 1 if stack is empty else return 0.


int isEmpty() {
}
//Push the character into stack
void push(int x) {
}

//pop a character from stack


int pop() {
}

//Output Format - Result : <result> if the input postfix expression is vaild.


//Output Format - Invalid postfix expression,. - if the input expression is invalid.
//postfix expression is given as the parameter.
void evaluatePostfix(char * e) {
}

//Read a postfix expression and evaluate it.


int main() {
char exp[20];
char *e, x;
printf("Enter the postfix expression : ");
scanf("%s",exp);
e = exp;
evaluatePostfix(e);

}*/

Output:
Enter·the·postfix·expression·:·234+-
Result·:·-5⏎
11. Implement a program to check for balanced parentheses using a stack.

Problem statement: To check for balanced parentheses using a stack.


Description: If the current character is a starting bracket ('(' or '{' or '[') then push it to stack.
If the current character is a closing bracket (')' or '}' or ']') then pop from stack and if the popped
character is the matching starting bracket then fine else brackets are not balanced.

Algorithm to Check Balanced Parentheses in C using Stack

1. Initialize an empty stack.


2. Iterate i from 0 to length(expression).
o Store the current character in a variable ‘ch’.
o If stack is empty: Push ‘ch’ to the stack
o Else if current character is a closing bracket and of the top of the stack
contains an opening bracket of the same type then remove the top of the stack:
Else, push ‘ch’ to the stack
3. If the stack is empty, return true, else false.

Example:

Input:

“({[]})”

Output:

true
Stack Expression Action

({[]}) Push

( {[]}) Push

({ []}) Push

({[ ]}) Pop

({ }) Pop

( ) Pop

Empty

As the stack is empty, hence the given expression was balanced.


Source code:

#include<stdio.h>
#include<conio.h>
#include<string.h>
#define STACK_MAX_SIZE 30
char arr[STACK_MAX_SIZE];
int top = -1;
void push(char element) {
if(top == STACK_MAX_SIZE - 1) {
printf("Stack is overflow\n");
} else {
top = top + 1;
arr[top] = element;
}
}
char pop() {
long int x;
if(top < 0) {
printf("Stack is underflow\n");
} else {
x = arr[top];
top = top - 1;

}return x;
}
int isempty() {
if(top == -1)
return 1;
else
return 0;
}
int isBalanced(char exp[]) {
int n = strlen(exp);
int i = 0;
char x;
for(i=0; i<n ;i++) {
if(exp[i] == '(' || exp[i] == '{' || exp[i] == '[') {
push(exp[i]);
} else if(exp[i] == ')' || exp[i] == '}' || exp[i] == ']') {
if(isempty()) {
return 0;
} else {
switch(exp[i]) {
case ')' :
x = pop();
if(x == '{' || x == '[') {
return 0;
}
break;
case ']' :
x = pop();
if(x == '{' || x == '(') {
return 0;
}
break;
case '}' :
x = pop();
if(x == '[' || x == '(') {
return 0;
}
break;
}
}
}
}
return isempty();
}
void main() {
char ch[80], temp;
printf("Enter an expression: ");
scanf("%s", ch);
if(isBalanced(ch) == 1) {
printf("balanced\n");
} else {
printf("not balanced\n");
}
}
Output:
Enter·an·expression:·1+2*3+(3+4)
balanced⏎
12. Implement a queue using linked lists.

Problem Statement: To implement a queue using linked lists.

Description: A queue is a linear data structure that follows the First In, First Out (FIFO)
principle, which means that the element which is inserted first in the queue will be the first one
to be removed from the queue. A good example of a queue is a queue of customers purchasing
a train ticket, where the customer who comes first will be served first.
A linked queue is shown here:

The two main operations performed on the linked queue are:

• Insertion
• Deletion

Algorithm for Insertion:

Step 1: Allocate the space for the new node PTR


Step 2: SET PTR -> DATA = VAL
Step 3: IF FRONT = NULL
SET FRONT = REAR = PTR
SET FRONT -> NEXT = REAR -> NEXT = NULL
ELSE
SET REAR -> NEXT = PTR
SET REAR = PTR
SET REAR -> NEXT = NULL
[END OF IF]
Step 4: END

Algorithm for Deletion:


Step 1: IF FRONT = NULL
Write " Underflow "
Go to Step 5
[END OF IF]
Step 2: SET PTR = FRONT
Step 3: SET FRONT = FRONT -> NEXT
Step 4: FREE PTR
Step 5: END
Example:
Source code:

#include <stdlib.h>
#include <stdio.h>
#include "QueueOperationsLL.c"
int main() {
int op, x;
while(1) {
printf("1.Enqueue 2.Dequeue 3.Display 4.Is Empty 5.Size 6.Exit\n");
printf("Option: ");
scanf("%d",&op);
switch(op) {
case 1:
printf("element: ");
scanf("%d",&x);
enqueue(x);
break;
case 2:
dequeue();
break;
case 3:
display();
break;
case 4:
isEmpty();
break;
case 5:
size();
break;
case 6: exit(0);
}
}
}

“QueueOperationsLL.c":
struct queue {
int data;
struct queue *next;
};

typedef struct queue *Q;


Q front = NULL, rear = NULL;

void enqueue(int element) {


Q temp = NULL;
temp = (Q)malloc(sizeof(struct queue));
if(temp == NULL) {
printf("Queue is overflow\n");
} else {
temp -> data = element;
temp -> next = NULL;

if(front == NULL) {
front = temp;
} else {
rear -> next = temp;
}
rear = temp;
printf("Successfully inserted\n");
}
}

void dequeue() {
Q temp = NULL;
if(front == NULL) {
printf("Queue is underflow\n");
} else {
temp = front;
if (front == rear) {
front = rear = NULL;
} else {
front = front -> next;
}
printf("Deleted value: %d\n", temp -> data);
free(temp);
}
}
void display() {
if(front == NULL) {
printf("Queue is empty\n");
} else {
Q temp = front;
printf("Elements: ");
while(temp != NULL) {
printf("%d ", temp -> data);
temp = temp -> next;
}
printf("\n");
}
}
void size() {
int count =0;
if(front == NULL) {
printf("Queue size: 0\n");
} else {
Q temp = front;
while(temp != NULL) {
temp = temp -> next;
count = count + 1;
}
printf("Queue size: %d\n",count);
}
}

void isEmpty() {
if(front == NULL ) {
printf("Queue is empty\n");
} else {
printf("Queue is not empty\n");
}
}

Out put:

1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·2
Queue·is·underflow⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·3
Queue·is·empty⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·4
Queue·is·empty⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·5
Queue·size:·0⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·1
element:·44
Successfully·inserted⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·1
element:·55
Successfully·inserted⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·1
element:·66
Successfully·inserted⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·1
element:·67
Successfully·inserted⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·3
Elements:·44·55·66·67·⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·2
Deleted·value:·44⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·2
Deleted·value:·55⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·5
Queue·size:·2⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·4
Queue·is·not·empty⏎
1.Enqueue·2.Dequeue·3.Display·4.Is·Empty·5.Size·6.Exit⏎
Option:·6
13. Implement a Circular Queue using arrays.
Problem statement: To implement a Circular Queue using arrays.
Description: A Circular Queue is an extended version of a normal queue where the last
element of the queue is connected to the first element of the queue forming a circle. The
operations are performed based on FIFO (First In First Out) principle. It is also called 'Ring
Buffer'.

Operations on Circular Queue:


• Front: Get the front item from the queue.
• Rear: Get the last item from the queue.
• enQueue(value) This function is used to insert an element into the circular queue. In
a circular queue, the new element is always inserted at the rear position.
o Check whether the queue is full – [i.e., the rear end is in just before the front
end in a circular manner].
o If it is full then display Queue is full.
▪ If the queue is not full then, insert an element at the end of the queue.
• deQueue() This function is used to delete an element from the circular queue. In a
circular queue, the element is always deleted from the front position.
o Check whether the queue is Empty.
o If it is empty then display Queue is empty.
▪ If the queue is not empty, then get the last element and remove it from
the queue.
Algorithms to implement Circular Queue using Array:
1. Initialize an array queue of size n, where n is the maximum number of elements that
the queue can hold.
2. Initialize two variables front and rear to -1.
3. Enqueue: To enqueue an element x into the queue, do the following:
o Increment rear by 1.
▪ If rear is equal to n, set rear to 0.
o If front is -1, set front to 0.
o Set queue[rear] to x.
4. Dequeue: To dequeue an element from the queue, do the following:
o Check if the queue is empty by checking if front is -1.
▪ If it is, return an error message indicating that the queue is empty.
o Set x to queue[front].
o If front is equal to rear, set front and rear to -1.
o Otherwise, increment front by 1 and if front is equal to n, set front to 0.
o Return x.
Source code :

#include <stdio.h>
#include<stdlib.h>
#include<stdio_ext.h>
#define MAX 6
int cq[MAX];
int front = -1, rear = -1;

void insert(int);
void delete();
void display();
void main()
{ int ch, item;
while(1)
{ printf("~~Main Menu~~");
printf("\n=> 1. Insertion and Overflow Demo");
printf("\n=> 2. Deletion and Underflow Demo");
printf("\n=> 3. Display");
printf("\n=> 4. Exit");
printf("\nEnter Your Choice: ");
scanf("%d", &ch);
__fpurge(stdin);
switch(ch)
{ case 1: printf("Enter the element to be inserted: ");
scanf("%d", &item);
insert(item);
break;
case 2: delete();
break;
case 3: display();
break;
case 4: exit(0);
default: printf("Please enter a valid choice\n");
}
}
}

void insert(int item)


{ if(front == (rear+1)%MAX)
{ printf("~~~Circular Queue Overflow~~~\n"); }
else
{ if(front == -1)
front = rear = 0;
else
rear = (rear+1)%MAX;
cq[rear] = item;
}
}

void delete()
{ char item;
if(front == -1)
{ printf("~~~Circular Queue Underflow~~~\n"); }
else
{ item = cq[front];
printf("Deleted element from the queue is: %d\n",item );
if(front == rear)
front = rear = -1;
else
front = (front+1)%MAX;
}
}

void display ()
{ int i ;
if(front == -1)
{ printf("~~~Circular Queue Empty~~~\n"); }
else
{ printf("Circular Queue contents are:\n");
for(i = front; i != rear ; i = (i+1)%MAX)
{ printf("%d ", cq[i]); }
printf("%d\n", cq[i]);
}
}

Out put :
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·1
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·2
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·3
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·4
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·5
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·3
Circular·Queue·contents·are:⏎
1·2·3·4·5⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·6
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·3
Circular·Queue·contents·are:⏎
1·2·3·4·5·6⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·1
Enter·the·element·to·be·inserted:·7
~~~Circular·Queue·Overflow~~~⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·3
Circular·Queue·contents·are:⏎
1·2·3·4·5·6⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·2
Deleted·element·from·the·queue·is:·1⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·2
Deleted·element·from·the·queue·is:·2⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·2
Deleted·element·from·the·queue·is:·3⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·3
Circular·Queue·contents·are:⏎
4·5·6⏎
~~Main·Menu~~⏎
=>·1.·Insertion·and·Overflow·Demo⏎
=>·2.·Deletion·and·Underflow·Demo⏎
=>·3.·Display⏎
=>·4.·Exit⏎
Enter·Your·Choice:·4
14.Write a Program to convert an infix expression to postfix and evaluate it.

Problem statement: To convert an infix expression to postfix and evaluate it.

Description: Infix expression: The expression of the form “a operator b” (a + b) i.e., when
an operator is in-between every pair of operands.
Postfix expression: The expression of the form “a b operator” (ab+) i.e., When every pair of
operands is followed by an operator.
To convert infix expression to postfix expression, use the stack data structure. Scan the infix
expression from left to right. Whenever we get an operand, add it to the postfix expression and
if we get an operator or parenthesis add it to the stack by maintaining their precedence.

Algorithm to Convert Infix to Postfix Program in C

• Start scanning the given expression from left to right.


• If the scanned character is an operand, just print it.
• Else
o If the precedence of the operand is higher than the precedence of the operator
the stack(or stack is empty or has'(‘), then push the operator in the stack.
o Else, Pop all the operators, that have greater or equal precedence than the
scanned operator. Once you pop them push this scanned operator. (If we see a
parenthesis while popping then stop and push the scanned operator in the
stack)
• If the scanned character is an ‘(‘, push it to the stack.
• If the scanned character is an ‘)’, pop the stack and output it until a ‘(‘ is encountered,
and discard both the parenthesis.
• Now, we should repeat steps 2 – 6 until the whole infix i.e. whole characters are
scanned.
• Print output
• Do the pop and output (print) until the stack is not empty

Example:

consider the infix expression exp = “a+b*c+d”


and the infix expression is scanned using the iterator i, which is initialized as i = 0.

• 1st Step: Here i = 0 and exp[i] = ‘a’ i.e., an operand. So add this in the postfix
expression. Therefore, postfix = “a”.

• Add ‘a’ in the postfix


• 2nd Step: Here i = 1 and exp[i] = ‘+’ i.e., an operator. Push this into the stack.
postfix = “a” and stack = {+}.

• Push ‘+’ in the stack


• 3rd Step: Now i = 2 and exp[i] = ‘b’ i.e., an operand. So add this in the postfix
expression. postfix = “ab” and stack = {+}.

• Add ‘b’ in the postfix


• 4th Step: Now i = 3 and exp[i] = ‘*’ i.e., an operator. Push this into the stack. postfix
= “ab” and stack = {+, *}.

• Push ‘*’ in the stack


• 5th Step: Now i = 4 and exp[i] = ‘c’ i.e., an operand. Add this in the postfix
expression. postfix = “abc” and stack = {+, *}.

• Add ‘c’ in the postfix


• 6th Step: Now i = 5 and exp[i] = ‘+’ i.e., an operator. The topmost element of the
stack has higher precedence. So pop until the stack becomes empty or the top element
has less precedence. ‘*’ is popped and added in postfix. So postfix = “abc*” and
stack = {+}.
• Pop ‘*’ and add in postfix
• Now top element is ‘+‘ that also doesn’t have less precedence. Pop it. postfix =
“abc*+”.

• Pop ‘+’ and add it in postfix


• Now stack is empty. So push ‘+’ in the stack. stack = {+}.

• Push ‘+’ in the stack


• 7th Step: Now i = 6 and exp[i] = ‘d’ i.e., an operand. Add this in the postfix
expression. postfix = “abc*+d”.

• Add ‘d’ in the postfix


• Final Step: Now no element is left. So empty the stack and add it in the postfix
expression. postfix = “abc*+d+”.

• Pop ‘+’ and add it in postfix


Evaluation of Postfix Expression using Stack:

Iterate the expression from left to right and keep on storing the operands into a stack. Once an
operator is received, pop the two topmost elements and evaluate them and push the result in
the stack again.
Algorithm:
Follow the steps mentioned below to evaluate postfix expression using stack:
• Create a stack to store operands (or values).
• Scan the given expression from left to right and do the following for every scanned
element.
o If the element is a number, push it into the stack.
o If the element is an operator, pop operands for the operator from the stack.
Evaluate the operator and push the result back to the stack.
• When the expression is ended, the number in the stack is the final answer.
Example: Consider the expression: exp = “2 3 1 * + 9 -“

• Scan 2, it’s a number, So push it into stack. Stack contains ‘2’.

Push 2 into stack

• Scan 3, again a number, push it to stack, stack now contains ‘2 3’ (from bottom to
top)

Push 3 into stack

• Scan 1, again a number, push it to stack, stack now contains ‘2 3 1’


Push 1 into stack

• Scan *, it’s an operator. Pop two operands from stack, apply the * operator on
operands. We get 3*1 which results in 3. We push the result 3 to stack. The stack now
becomes ‘2 3’.

Evaluate * operator and push result in stack

• Scan +, it’s an operator. Pop two operands from stack, apply the + operator on
operands. We get 3 + 2 which results in 5. We push the result 5 to stack. The stack
now becomes ‘5’.
Evaluate + operator and push result in stack

• Scan 9, it’s a number. So we push it to the stack. The stack now becomes ‘5 9’.

Push 9 into stack

• Scan -, it’s an operator, pop two operands from stack, apply the – operator on
operands, we get 5 – 9 which results in -4. We push the result -4 to the stack. The
stack now becomes ‘-4’.
Source code :

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

#define MAX_SIZE 100

int isOperator(char ch); // Function prototype for isOperator

// Define a stack structure


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

// Function to initialize the stack


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

// Function to check if the stack is empty


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

// Function to push an item onto the stack


void push(struct Stack* stack, char item) {
if (stack->top == MAX_SIZE - 1) {
printf("Stack overflow\n");
exit(EXIT_FAILURE);
}
stack->items[++stack->top] = item;
}

// Function to pop an item from the stack


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

// Function to get the precedence of an operator


int getPrecedence(char op) {
if (op == '+' || op == '-')
return 1;
else if (op == '*' || op == '/' || op == '%')
return 2;
else
return 0; // For '('
}

// Function to peek at the top of the stack without popping


char peek(struct Stack* stack) {
return stack->items[stack->top];
}

int isOperator(char ch) {


return (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '%');
}

// Function to convert infix expression to postfix notation


void infixToPostfix(char* infix, char* postfix) {
struct Stack operatorStack;
initializeStack(&operatorStack);

int i, j;
char token;

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


token = infix[i];

if (isdigit(token)) {
postfix[j++] = token;
} else if (token == '(') {
push(&operatorStack, token);
} else if (token == ')') {
while (!isStackEmpty(&operatorStack) && peek(&operatorStack) != '(') {
postfix[j++] = pop(&operatorStack);
}
pop(&operatorStack); // Pop '('
} else if (isOperator(token)) {
while (!isStackEmpty(&operatorStack) && getPrecedence(peek(&operatorStack)) >=
getPrecedence(token)) {
postfix[j++] = pop(&operatorStack);
}
push(&operatorStack, token);
}
}
// Pop remaining operators from the stack
while (!isStackEmpty(&operatorStack)) {
postfix[j++] = pop(&operatorStack);
}

postfix[j] = '\0';
}

// Function to evaluate a postfix expression


int evaluatePostfixExpression(char* postfix) {
struct Stack operandStack;
initializeStack(&operandStack);

int i, operand1, operand2;


char token;

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


token = postfix[i];

if (isdigit(token)) {
push(&operandStack, token - '0'); // Convert char to int
} else if (isOperator(token)) {
operand2 = pop(&operandStack);
operand1 = pop(&operandStack);

switch (token) {
case '+':
push(&operandStack, operand1 + operand2);
break;
case '-':
push(&operandStack, operand1 - operand2);
break;
case '*':
push(&operandStack, operand1 * operand2);
break;
case '/':
push(&operandStack, operand1 / operand2);
break;
case '%':
push(&operandStack, operand1 % operand2);
break;
}
}
}

// The result is on the top of the stack


return pop(&operandStack);
}

int main() {
char infixExpression[MAX_SIZE];
char postfixExpression[MAX_SIZE];

printf("Infix expression: ");


scanf("%s", infixExpression);

infixToPostfix(infixExpression, postfixExpression);

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

int result = evaluatePostfixExpression(postfixExpression);

printf("Result: %d\n", result);

return 0;
}

Out put :
Infix·expression:·2+3*4
Postfix·expression:·234*+⏎
Result:·14⏎
15. Create a program to determine whether a given string is a palindrome or not using a
stack.
Problem statement: To determine whether a given string is a palindrome or not using a stack.

Description: A string is said to be palindrome if the reverse of the string is the same as the
string.

• Find the length of the string say len. Now, find the mid as mid = len / 2.
• Push all the elements till mid into the stack i.e. str[0…mid-1].
• If the length of the string is odd then neglect the middle character.
• Till the end of the string, keep popping elements from the stack and compare them
with the current character i.e. string[i].
• If there is a mismatch then the string is not a palindrome. If all the elements match
then the string is a palindrome.

Example: Consider the string "radar". Its character comparison would be as follows:

index: 0 1 2 3 4

value: r a d a r
To compare it with the reverse of itself, the following logic is used:

1. The 0th character in the char array, string1, is the same as the 4th character in the
same string.
2. 1st character is the same as 3rd character.
3. 2nd character is the same as 2nd character.
4. . . . .
5. ith character is the same as the 'length-i-1'th character.
6. If any of the above conditions fails, the flag is set to true(1), implying that the string is
not a palindrome.
7. By default, the value of the flag is false(0). Hence, the string is a palindrome if all the
conditions are satisfied.

Source code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

struct Stack {
int top;
char items[100];
};
// Write a function to initialize the stack
void initializeStack(struct Stack* stack) {
stack->top = -1;
}
// Write a function to check if the stack is empty
int isStackEmpty(struct Stack* stack) {
return (stack->top == -1);
}
// Write a function to push a character onto the stack
void push(struct Stack* stack, char item) {
if (stack->top == 99) {
printf("Stack overflow\n");
exit(EXIT_FAILURE);
}
stack->items[++stack->top] = item;
}

// Write a function to pop a character from the stack

char pop(struct Stack* stack) {


if (isStackEmpty(stack)) {
printf("Stack underflow\n");
exit(EXIT_FAILURE);
}
return stack->items[stack->top--];
}
// Write a function to check if a given string is a palindrome
int isPalindrome(char* str) {
struct Stack charStack;
initializeStack(&charStack);

int i, len;

// Push the characters of the first half of the string onto the stack
len = strlen(str);
for (i = 0; i < len / 2; ++i) {
push(&charStack, tolower(str[i])); // Convert to lowercase for case-insensitivity
}
// If the string has an odd length, skip the middle character
if (len % 2 != 0) {
i++;
}

// Pop and compare with the remaining characters


while (str[i] != '\0') {
if (tolower(str[i]) != pop(&charStack)) {
return 0; // Not a palindrome
}
i++;
}

return 1; // Palindrome
}

int main() {
char inputString[100];

printf("String: ");
scanf("%s", inputString);

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

return 0;
}

Output:
String:·Madam
Madam·is·a·palindrome⏎
16.Write a program to implement graph traversal using BFS.

Problem statement: To implement graph traversal using BFS.

Description: The Breadth First Search (BFS) algorithm is used to search a graph data
structure for a node that meets a set of criteria. It starts at the root of the graph and visits all
nodes at the current depth level before moving on to the nodes at the next depth level.

BFS Algorithm

1. Start with the initial node.


2. Mark the initial node as visited and enqueue it.
3. While the queue is not empty:

• Dequeue a node from the queue.


• If the dequeued node is the goal node, stop the search.
• Otherwise, enqueue any successors (nodes that are directly connected to the dequeued
node) that have not yet been visited.

4. If the queue is empty, every node on the graph has been visited, or there is no path from
the initial node to the goal node.
5. If the goal node was found, return the path that was followed.

Example: Let us understand the working of the algorithm with the help of the following
example.

Step1: Initially queue and visited arrays are empty.

Queue and visited arrays are empty initially.

Step2: Push node 0 into queue and mark it visited.

Push node 0 into queue and mark it visited.


Step 3: Remove node 0 from the front of queue and visit the unvisited neighbours and push
them into queue.

Remove node 0 from the front of queue and visited the unvisited neighbours and push into
queue.

Step 4: Remove node 1 from the front of queue and visit the unvisited neighbours and push
them into queue.

Remove node 1 from the front of queue and visited the unvisited neighbours and push

Step 5: Remove node 2 from the front of queue and visit the unvisited neighbours and push
them into queue.

Remove node 2 from the front of queue and visit the unvisited neighbours and push them into
queue.

Step 6: Remove node 3 from the front of queue and visit the unvisited neighbours and push
them into queue.
As we can see that every neighbours of node 3 is visited, so move to the next node that are in
the front of the queue.
Remove node 3 from the front of queue and visit the unvisited neighbours and push them into
queue.

Steps 7: Remove node 4 from the front of queue and visit the unvisited neighbours and push
them into queue.
As we can see that every neighbours of node 4 are visited, so move to the next node that is in
the front of the queue.

Remove node 4 from the front of queue and visit the unvisited neighbours and push them into
queue.

Now, Queue becomes empty, So, terminate these process of iteration.

Source code:
#include <stdio.h>
#include <stdlib.h>
#define MAX 99
struct node {
struct node *next;
int vertex;
};
typedef struct node * GNODE;
GNODE graph[20];
int visited[20];
int queue[MAX], front = -1,rear = -1;
int n;

void insertQueue(int vertex) {


if(rear == MAX-1)
printf("Queue Overflow.\n");
else {
if(front == -1)
front = 0;
rear = rear+1;
queue[rear] = vertex ;
}
}

int isEmptyQueue() {
if(front == -1 || front > rear)
return 1;
else
return 0;
}

int deleteQueue() {
int deleteItem;
if(front == -1 || front > rear) {
printf("Queue Underflow\n");
exit(1);
}
deleteItem = queue[front];
front = front+1;
return deleteItem;
}

void BFS(int v) {
int w;
insertQueue(v);
while(!isEmptyQueue()) {
v = deleteQueue( );
printf("\n%d",v);
visited[v]=1;
GNODE g = graph[v];
for(;g!=NULL;g=g->next) {
w=g->vertex;
if(visited[w]==0) {
insertQueue(w);
visited[w]=1;
}
}
}
}

void main() {
int N, E, s, d, i, j, v;
GNODE p, q;
printf("Enter the number of vertices : ");
scanf("%d",&N);
printf("Enter the number of edges : ");
scanf("%d",&E);
for(i=1;i<=E;i++) {
printf("Enter source : ");
scanf("%d",&s);
printf("Enter destination : ");
scanf("%d",&d);
q=(GNODE)malloc(sizeof(struct node));
q->vertex=d;
q->next=NULL;
if(graph[s]==NULL) {
graph[s]=q;
} else {
p=graph[s];
while(p->next!=NULL)
p=p->next;
p->next=q;
}
}
for(i=1;i<=n;i++)
visited[i]=0;
printf("Enter Start Vertex for BFS : ");
scanf("%d", &v);
printf("BFS of graph : ");
BFS(v);
printf("\n");
}
Output:
Enter·the·number·of·vertices·:·5
Enter·the·number·of·edges·:·5
Enter·source·:·1
Enter·destination·:·2
Enter·source·:·1
Enter·destination·:·4
Enter·source·:·4
Enter·destination·:·2
Enter·source·:·2
Enter·destination·:·3
Enter·source·:·4
Enter·destination·:·5
Enter·Start·Vertex·for·BFS·:·1
BFS·of·graph·:·⏎
1⏎
2⏎
4⏎
3⏎
5⏎
17.Write a program to implement graph traversal using DFS.

Problem statement: To implement graph traversal using DFS.


Description: Depth First Traversal (or DFS) for a graph is similar to Depth First Traversal of
a tree. The only catch here is, that, unlike trees, graphs may contain cycles (a node may be
visited twice). To avoid processing a node more than once, use a boolean visited array. A graph
can have more than one DFS traversal.

Algorithm:

• Initially all vertices are marked unvisited (false).


• The DFS algorithm starts at a vertex u in the graph. By starting at vertex u it
considers the edges from u to other vertices.
o If the edge leads to an already visited vertex, then backtrack to current vertex
u.
o If an edge leads to an unvisited vertex, then go to that vertex and start
processing from that vertex. That means the new vertex becomes the current
root for traversal.
• Follow this process until a vertices are marked visited.

Example: We use an undirected graph with 5 vertices.

We start from vertex 1, the DFS algorithm starts by putting it in the Visited list and putting all
its adjacent vertices in the stack.

Next, we visit the element at the top of stack i.e. 2 and go to its adjacent nodes. Since 1 has
already been visited, we visit 3 instead.
Vertex 3 has an unvisited adjacent vertex in 5, so we add that to the top of the stack and visit
it.

After we visit the last element 4, it doesn't have any unvisited adjacent nodes, so we have
completed the Depth First Traversal of the graph.

Source code:

#include<stdio.h>
#include<stdlib.h>
struct node {
struct node *next;
int vertex;
};
typedef struct node * GNODE;
GNODE graph[20];
int visited[20];
int n;

void DFS(int i) {
GNODE p;
printf("\n%d",i);
p=graph[i];
visited[i]=1;
while(p!=NULL) {
i=p->vertex;
if(!visited[i])
DFS(i);
p=p->next;
}

void main() {
int N,E,i,s,d,v;
GNODE q,p;
printf("Enter the number of vertices : ");
scanf("%d",&N);
printf("Enter the number of edges : ");
scanf("%d",&E);
for(i=1;i<=E;i++) {
printf("Enter source : ");
scanf("%d",&s);
printf("Enter destination : ");
scanf("%d",&d);
q=(GNODE)malloc(sizeof(struct node));
q->vertex=d;
q->next=NULL;
if(graph[s]==NULL)
graph[s]=q;
else {
p=graph[s];
while(p->next!=NULL)
p=p->next;
p->next=q;
}
}
for(i=0;i<n;i++)
visited[i]=0;
printf("Enter Start Vertex for DFS : ");
scanf("%d", &v);
printf("DFS of graph : ");
DFS(v);
printf("\n");
}
Output:
Enter·the·number·of·vertices·:·6
Enter·the·number·of·edges·:·7
Enter·source·:·1
Enter·destination·:·2
Enter·source·:·1
Enter·destination·:·4
Enter·source·:·4
Enter·destination·:·2
Enter·source·:·2
Enter·destination·:·3
Enter·source·:·4
Enter·destination·:·5
Enter·source·:·4
Enter·destination·:·3
Enter·source·:·3
Enter·destination·:·6
Enter·Start·Vertex·for·DFS·:·1
DFS·of·graph·:·⏎
1⏎
2⏎
3⏎
6⏎
4⏎
5⏎
18.Write a program to implement linear probing.

Problem statement: To implement linear probing.

Description: Linear probing in Hashing is a collision resolution method used in hash tables.
Collisions occur when two keys produce the same hash value, attempting to map to the same
array index. Linear probing deals with these collisions by searching for the next available slot
linearly in the array until an empty slot is found.

Procedure: Below is a hash function that calculates the next location. If the location is empty
then store value otherwise find the next location.
Following hash function is used to resolve the collision in:
h(k, i) = [h(k) + i] mod m

Where

m = size of the hash table,


h(k) = (k mod m),
i = the probe number that varies from 0 to m–1.

Therefore, for a given key k, the first location is generated by [h(k) + 0] mod m, the first time
i=0.

If the location is free, the value is stored at this location. If value successfully stores then
probe count is 1 means location is founded on the first go.
If location is not free then second probe generates the address of the location given by [h(k)
+ 1]mod m.
Similarly, if the generated location is occupied, then subsequent probes generate the address
as [h(k) + 2]mod m, [h(k) + 3]mod m, [h(k) + 4]mod m, [h(k) + 5]mod m, and so on, until
a free location is found.

Linear Probing Example

Insert the following sequence of keys in the hash table


{9, 7, 11, 13, 12, 8}
Use linear probing technique for collision resolution
h(k, i) = [h(k) + i] mod m
h(k) = 2k + 5
m=10
Step 01:

First Draw an empty hash table of Size 10.


The possible range of hash values will be [0, 9].
Step 02:

Insert the given keys one by one in the hash table.


First Key to be inserted in the hash table = 9.
h(k) = 2k + 5
h(9) = 2*9 + 5 = 23
h(k, i) = [h(k) + i] mod m
h(9, 0) = [23 + 0] mod 10 = 3
So, key 9 will be inserted at index 3 of the hash table

Step 03:

Next Key to be inserted in the hash table = 7.


h(k) = 2k + 5
h(7) = 2*7 + 5 = 19
h(k, i) = [h(k) + i] mod m
h(7, 0) = [19 + 0] mod 10 = 9
So, key 7 will be inserted at index 9 of the hash table

Step 04:

Next Key to be inserted in the hash table = 11.


h(k) = 2k + 5
h(11) = 2*11 + 5 = 27
h(k, i) = [h(k) + i] mod m
h(11, 0) = [27 + 0] mod 10 = 7
So, key 11 will be inserted at index 7 of the hash table

Step 05:

Next Key to be inserted in the hash table = 13.


h(k) = 2k + 5
h(13) = 2*13 + 5 = 31
h(k, i) = [h(k) + i] mod m
h(13, 0) = [31 + 0] mod 10 = 1
So, key 13 will be inserted at index 1 of the hash table
Step 06:

Next key to be inserted in the hash table = 12.


h(k) = 2k + 5
h(12) = 2*12 + 5 = 27
h(k, i) = [h(k) + i] mod m
h(12, 0) = [27 + 0] mod 10 = 7

Here Collision has occurred because index 7 is already filled.

Now we will increase i by 1.


h(12, 1) = [27 + 1] mod 10 = 8
So, key 12 will be inserted at index 8 of the hash table.

Step 07:

Next key to be inserted in the hash table = 8.


h(k) = 2k + 5
h(8) = 2*8 + 5 = 21
h(k, i) = [h(k) + i] mod m
h(8, 0) = [21 + 0] mod 10 = 1
Here Collision has occurred because index 1 is already filled.

Now we will increase i by 1 now i become 1.

h(k) = 2k + 5
h(8) = 2*8 + 5 = 21
h(k, i) = [h(k) + i] mod m
h(8, 0) = [21 + 1] mod 10 = 2

index 2 is vacant so 8 will be inserted at index 2.

This is how the linear probing collision resolution technique works.

Source code (a):


#include <stdio.h>
#include <stdlib.h>
#include "HashingLinearProbing.c"
int main() {
int x, op, i = 0;
for (i = 0; i < SIZE; i++)
HashTable[i] = -1;
while (1) {
printf("1.Insert 2.Delete 3.Search 4.Print 5.Exit\n");
printf("Enter your option : ");
scanf("%d", &op);
switch (op) {
case 1: printf("Enter an element to be inserted : ");
scanf("%d", &x);
insert(x);
break;
case 2:
printf("Enter an element to be deleted : ");
scanf("%d", &x);
deleteElement(x);
break;
case 3:
printf("Enter an element to be searched : ");
scanf("%d", &x);
search(x);
break;
case 4:
print();
break;
case 5: exit(0);
}
}
}

"HashingLinearProbing.c":
#define SIZE 10
int HashTable[SIZE];
int hash(int x) {
return x % SIZE;
}
void insert(int x) {
int index = hash(x);
int start = index;
while (HashTable[index] != -1) {
if (HashTable[index] == -1) {
break;
}
index = (index+1) % SIZE;
if(index == start) {
printf("Hash table is full.\n");
return;
}
}
HashTable[index] = x;
printf("Successfully inserted.\n");
}
void deleteElement(int x) {
int index = hash(x);
int start = index;
while (HashTable[index] != x) {
if (HashTable[index] == x) {
break;
}
index = (index+1) % SIZE;
if(index == start) {
printf("Element not found. So cannot delete the element.\n");
return;
}
}
HashTable[index] = -1;
printf("Successfully deleted.\n");
}
void search(int x) {
int index = hash(x);
int start = index;
while (HashTable[index] != x) {
if (HashTable[index] == x) {
break;
}
index = (index+1) % SIZE;
if(index == start) {
printf("Element not found.\n");
return;
}
}
printf("Element found.\n");
}
void print() {
int i=0;
for(;i<SIZE;i++) {
if(HashTable[i] != -1)
printf("[%d]=>%d ",i,HashTable[i]);
}
printf("\n");
}

Out put :

1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·1
Enter·an·element·to·be·inserted·:·11
Successfully·inserted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·1
Enter·an·element·to·be·inserted·:·22
Successfully·inserted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·1
Enter·an·element·to·be·inserted·:·33
Successfully·inserted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·1
Enter·an·element·to·be·inserted·:·43
Successfully·inserted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·1
Enter·an·element·to·be·inserted·:·53
Successfully·inserted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·4
[1]=>11·[2]=>22·[3]=>33·[4]=>43·[5]=>53·⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·1
Enter·an·element·to·be·inserted·:·44
Successfully·inserted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·4
[1]=>11·[2]=>22·[3]=>33·[4]=>43·[5]=>53·[6]=>44·⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·3
Enter·an·element·to·be·searched·:·34
Element·not·found.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·2
Enter·an·element·to·be·deleted·:·33
Successfully·deleted.⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·4
[1]=>11·[2]=>22·[4]=>43·[5]=>53·[6]=>44·⏎
1.Insert·2.Delete·3.Search·4.Print·5.Exit⏎
Enter·your·option·:·5

19. Write a program to implement binary tree traversals using linked list with recursion.
Problem statement: To implement binary tree traversals using linked list with recursion.
Description : Unlike linear data structures (Array, Linked List, Queues, Stacks, etc) which
have only one logical way to traverse them, trees can be traversed in different ways.
A Tree Data Structure can be traversed in following ways:
1.Depth First Search or DFS
1. Inorder Traversal
2. Preorder Traversal
3. Postorder Traversal
2. Level Order Traversal or Breadth First Search or BFS
3. Boundary Traversal
4. Diagonal Traversal
Tree Traversals

Algorithm for Inorder Traversal:


1. Traverse the left subtree, i.e., call Inorder(left->subtree)
2. Visit the root.
3. Traverse the right subtree, i.e., call Inorder(right->subtree)

Uses of Inorder Traversal:


In the case of binary search trees (BST), Inorder traversal gives nodes in non-
decreasing order. To get nodes of BST in non-increasing order, a variation of Inorder
traversal where Inorder traversal is reversed can be used.

Algorithm for preorder Traversal:


1. Visit the root.
2. Traverse the left subtree, i.e., call Preorder(left->subtree)
3. Traverse the right subtree, i.e., call Preorder(right->subtree)

Uses of Preorder Traversal :


Preorder traversal is used to create a copy of the tree. Preorder traversal is also used to get
prefix expressions on an expression tree.

Algorithm for preorder Traversal:


1. Traverse the left subtree, i.e., call Postorder(left->subtree)
2. Traverse the right subtree, i.e., call Postorder(right->subtree)
3. Visit the root

Uses of Postorder Traversal:


Postorder traversal is used to delete the tree. Please see the question for the deletion of a
tree for details. Postorder traversal is also useful to get the postfix expression of an expression
tree.

Example of inorder traversal


• we start recursive call from 30(root) then move to 20 (20 also have sub tree so apply in order
on it),15 and 5.
• 5 have no child .so print 5 then move to it's parent node which is 15 print and then move to 15's
right node which is 18.
• 18 have no child print 18 and move to 20 .print 20 then move it right node which is 25 .25 have
no subtree so print 25.
• print root node 30 .
• now recursively traverse to right subtree of root node . so move to 40. 40 have subtree so
traverse to left subtree of 40.
• left subtree of 40 have only one node which is 35. 35 had no further subtree so print 35. move
to 40 and print 40.
• traverse to right subtree of 40. so move to 50 now have subtree so traverse to left subtree of 50
.move to 45 , 45 have no further subtree so print 45.
• move to 50 and print 50. now traverse to right subtree of 50 hence move to 60 and print 60.
• our final output is {5 , 15 , 18 , 20 , 25 , 30 , 35 , 40 , 45 , 50 , 60}

Example of preorder traversal

• Start with root node 30 .print 30 and recursively traverse the left subtree.
• next node is 20. now 20 have subtree so print 20 and traverse to left subtree of 20 .
• next node is 15 and 15 have subtree so print 15 and traverse to left subtree of 15.
• 5 is next node and 5 have no subtree so print 5 and traverse to right subtree of 15.
• next node is 18 and 18 have no child so print 18 and traverse to right subtree of 20.
• 25 is right subtree of 20 .25 have no child so print 25 and start traverse to right subtree of 30.
• next node is 40. node 40 have subtree so print 40 and then traverse to left subtree of 40.
• next node is 35. 35 have no subtree so print 35 and then traverse to right subtree of 40.
• next node is 50. 50 have subtree so print 50 and traverse to left subtree of 50.
• next node is 45. 45 have no subtree so print 45 and then print 60(right subtree) of 50.
• our final output is {30 , 20 , 15 , 5 , 18 , 25 , 40 , 35 , 50 , 45 , 60}

Example of postorder traversal

• We start from 30, and following Post-order traversal, we first visit the left subtree 20. 20 is also
traversed post-order.
• 15 is left subtree of 20 .15 is also traversed post order.
• 5 is left subtree of 15. 5 have no subtree so print 5 and traverse to right subtree of 15 .
• 18 is right subtree of 15. 18 have no subtree so print 18 and then print 15. post order traversal
for 15 is finished.
• next move to right subtree of 20.
• 25 is right subtree of 20. 25 have no subtree so print 25 and then print 20. post order traversal
for 20 is finished.
• next visit the right subtree of 30 which is 40 .40 is also traversed post-order(40 have subtree).
• 35 is left subtree of 40. 35 have no more subtree so print 35 and traverse to right subtree of 40.
• 50 is right subtree of 40. 50 should also traversed post order.
• 45 is left subtree of 50. 45 have no more subtree so print 45 and then print 60 which is right
subtree of 50.
• next print 50 . post order traversal for 50 is finished.
• now print 40 ,and post order traversal for 40 is finished.
• print 30. post order traversal for 30 is finished.
• our final output is {5 , 18 , 15 , 25 , 20 , 35 , 45 , 60 , 50 , 40 , 30}

Source code :
// Program for linked implementation of complete binary tree
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<stdbool.h>
#include"TreeStructure.c"
#include"Traversals.c"
// For Queue Size
#define SIZE 100000

// A utility function to create a new Queue


struct Queue* createQueue(int size)
{
struct Queue* queue = (struct Queue*) malloc(sizeof( struct Queue ));

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


queue->size = size;

queue->array = (struct node**) malloc


(queue->size * sizeof( struct node* ));

int i;
for (i = 0; i < size; ++i)
queue->array[i] = NULL;

return queue;
}

// Standard Queue Functions


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

int isFull(struct Queue* queue)


{ return queue->rear == queue->size - 1;

int hasOnlyOneItem(struct Queue* queue)


{ return queue->front == queue->rear;
}

void Enqueue(struct node *root, struct Queue* queue)


{
if (isFull(queue))
return;
queue->array[++queue->rear] = root;
if (isEmpty(queue))
++queue->front;
}
struct node* Dequeue(struct Queue* queue)
{
if (isEmpty(queue))
return NULL;
struct node* temp = queue->array[queue->front];

if (hasOnlyOneItem(queue))
queue->front = queue->rear = -1;
else
++queue->front;
return temp;
}

struct node* getFront(struct Queue* queue)


{ return queue->array[queue->front]; }

// A utility function to check if a tree node


// has both left and right children
int hasBothChild(struct node* temp)
{
return temp && temp->left && temp->right;
}

// Function to insert a new node in complete binary tree


void insert(struct node **root, int data, struct Queue* queue)
{
// Create a new node for given data
struct node *temp = newNode(data);
// If the tree is empty, initialize the root with new node.
if (!*root)
*root = temp;
else
{
// get the front node of the queue.
struct node* front = getFront(queue);

// If the left child of this front node doesn’t exist, set the
// left child as the new node
if (!front->left)
{
front->left = NULL;
front->left = temp;
}
// If the right child of this front node doesn’t exist, set the
// right child as the new node
else if (!front->right)
{
front->right = NULL;
front->right = temp;
}
// If the front node has both the left child and right child,
// Dequeue() it.
if (hasBothChild(front))
{
Dequeue(queue);
}
}
// Enqueue() the new node for later insertions
Enqueue(temp, queue);
}

// Standard level order traversal to test above function


void levelOrder(struct node* root)
{
struct Queue* queue = createQueue(SIZE);
Enqueue(root, queue);
while (!isEmpty(queue))
{
struct node* temp = Dequeue(queue);
printf("%d ", temp->data);
if (temp->left)
Enqueue(temp->left, queue);
if (temp->right)
Enqueue(temp->right, queue);
}
}

// Driver program to test above functions


int main()
{
struct node* T1 = NULL;
struct Queue* queue1 = createQueue(SIZE);
int ele;

while(1){
printf("Enter value : ");
scanf("%d",&ele);
if(ele==-1){
break;
}
else{
insert(&T1, ele, queue1);
}
}
inorder(T1);
printf("\n");
preorder(T1);
printf("\n");
postorder(T1);
}

"TreeStructure.c" :
// A tree node
struct node
{
int data;
struct node *right,*left;
struct node *root;
};

// A queue node
struct Queue
{
int front, rear;
int size;
struct node* *array;
};

// A utility function to create a new tree node


struct node* newNode(int data)
{
struct node* temp = (struct node*) malloc(sizeof( struct node ));
temp->data = data;
temp->left = temp->right = NULL;
return temp;
}

"Traversals.c" :
void inorder( struct node *ptr)
{
// write your code here to compute

if(ptr!=NULL)
{
inorder(ptr->left);
printf("%d ",ptr->data);
inorder(ptr->right);
}
// and print inorder traversal
}

void preorder( struct node *ptr){


// write your code here to compute
if(ptr!=NULL){
printf("%d ",ptr->data);
preorder(ptr->left);
preorder(ptr->right);
}
// and print preorder traversal
}

void postorder(struct node *ptr)


{
// write your code here to compute
if(ptr!=NULL)
{
postorder(ptr->left);
postorder(ptr->right);
printf("%d ",ptr->data);
}
// and print postorder traversal
}

Out put :

Enter·value·:·45
Enter·value·:·89
Enter·value·:·56
Enter·value·:·12
Enter·value·:·45
Enter·value·:·26
Enter·value·:·78
Enter·value·:·45
Enter·value·:·-1
45·12·89·45·45·26·56·78·⏎
45·89·12·45·45·56·26·78·⏎
45·12·45·89·26·78·56·45·
20.Write a c program to implement topological sorting on graph.
Problem statement: To implement topological sorting on graph.
Description : Topological Sorting is the process in which the main goal is to find an ordering
of vertices in a directed acyclic graph (DAG) that places vertex u before vertex v for any
directed edge (u, v). “Topological order” is the name given to this linear arrangement. If a
DAG contains cycles, it might not have any topological ordering at all.
Topological Sort Example

Solving Using In-degree Method


Step 1: Write in-degree of all vertices:
Vertex in-degree
1 0
2 1
3 1
4 2

Step 2: Write the vertex which has in-degree 0 (zero) in solution. Here vertex 1 has in-degree 0. So,

Solution is: 1 -> (not yet completed )

Decrease in-degree count of vertices who are adjacent to the vertex which recently added to the
solution.

Here vertex 1 is recently added to the solution. Vertices 2 and 3 are adjacent to vertex 1. So decrease
the in-degree count of those and update.

Updated result is:

Vertex in-degree
Already added
1
to solution
2 0
3 0
4 2
Again repeat the same thing which we have done in step1 that, write the vertices which have degree 0
in solution.
Here we can observe that two vertices (2 and 3) have in-degree 0 (zero). Add any vertex into the
solution.
Note that, you may add vertex 2 into solution, and I may add vertex 3 to solution. That means the
solution to topological sorting is not unique.
Now add vertex 3.
Solution is: 1->3->
Again decrease the in-degree count of vertices which are adjacent to vertex 3.
Updated result is:
Vertex in-degree
Already added
1
to solution
2 0
Already added
3
to solution
4 1
Now add vertex 2 to solution because it only has in-degree 0.
Solution is: 1->3->2->
Updated result is:
Vertex in-degree
Already added
1
to solution
Already added
2
to solution
Already added
3
to solution
4 0

Finally add 4 to solution.

Final solution is: 1->3->2->4

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

#define MAX 100

int n; /*Number of vertices in the graph*/


int adj[MAX][MAX]; /*Adjacency Matrix*/
void create_graph();
int queue[MAX], front = -1,rear = -1;
void insert_queue(int v);
int delete_queue();
int isEmpty_queue();

int indegree(int v);

int main()
{
int i,v,count,topo_order[MAX],indeg[MAX];

create_graph();

/*Find the indegree of each vertex*/


for(i=0;i<n;i++)
{
indeg[i] = indegree(i);
if( indeg[i] == 0 )
insert_queue(i);
}

count = 0;

while( !isEmpty_queue( ) && count < n )


{
v = delete_queue();
topo_order[++count] = v; /*Add vertex v to topo_order array*/
/*Delete all edges going fron vertex v */
for(i=0; i<n; i++)
{
if(adj[v][i] == 1)
{
adj[v][i] = 0;
indeg[i] = indeg[i]-1;
if(indeg[i] == 0)
insert_queue(i);
}
}
}

/*if( count < n )


{
printf("\nNo topological ordering possible, graph contains cycle\n");
exit(1);
}*/
printf("The topological order is:");
for(i=1; i<=count; i++)
printf("%d ",topo_order[i] + 1 );
printf("\n");

return 0;
}/*End of main()*/

void insert_queue(int vertex)


{
if (rear == MAX-1)
return;
else
{
if (front == -1) /*If queue is initially empty */
front = 0;
rear = rear+1;
queue[rear] = vertex ;
}
}/*End of insert_queue()*/

int isEmpty_queue()
{
if(front == -1 || front > rear )
return 1;
else
return 0;
}/*End of isEmpty_queue()*/

int delete_queue()
{
int del_item;
if (front == -1 || front > rear)
{
//printf("\nQueue Underflow\n");
exit(1);
}
else
{
del_item = queue[front];
front = front+1;
return del_item;
}
}/*End of delete_queue() */

int indegree(int v)
{
int i,in_deg = 0;
for(i=0; i<n; i++)
if(adj[i][v] == 1)
in_deg++;
return in_deg;
}/*End of indegree() */

void create_graph()
{
int i,max_edges,origin,destin;

printf("Enter the number of vertices : ");


scanf("%d",&n);
printf("Enter the number of edges : ");
scanf("%d",&max_edges);

for(i=1; i<=max_edges; i++)


{
printf("Enter source : ");
scanf("%d",&origin);
printf("Enter destination : ");
scanf("%d",&destin);

if((origin == -1) && (destin == -1))


break;

if( origin > n || destin > n || origin<=0 || destin<=0)


{
printf("Invalid index. Try again.\n");
i--;
continue;
}
else
adj[origin-1][destin-1] = 1;
}
}

Output:

Enter·the·number·of·vertices·:·4
Enter·the·number·of·edges·:·4
Enter·source·:·1
Enter·destination·:·4
Enter·source·:·2
Enter·destination·:·1
Enter·source·:·2
Enter·destination·:·3
Enter·source·:·4
Enter·destination·:·3
The·topological·order·is:2·1·4·3·⏎

You might also like