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

DS LAB Mannual

Same

Uploaded by

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

DS LAB Mannual

Same

Uploaded by

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

1

2
Experiment No.1

Aim: Implementation of Stack using Array

Theory: A stack data structure can be implemented using a one-dimensional array. But stack implemented
using array stores only a fixed number of data values. This implementation is very simple. Just define a one-
dimensional array of specific size and insert or delete the values into that array by using LIFO principle with
the help of a variable called 'top'. Initially, the top is set to -1. Whenever we want to insert a value into the
stack, increment the top value by one and then insert. Whenever we want to delete a value from the stack, then
delete the top value and decrement the top value by one.

❖ Stack operation using array


Before implementing actual operations, first follow the below steps to create an empty stack.
• Step 1 - Include all the header files which are used in the program and define a constant 'SIZE' with
specific value.
• Step 2 - Declare all the functions used in stack implementation.
• Step 3 - Create a one-dimensional array with fixed size (int stack [SIZE])
• Step 4 - Define a integer variable 'top' and initialize with '-1'. (int top = -1)
• Step 5 - In main method, display menu with list of operations and make suitable function calls to
perform operation selected by the user on the stack.

Push (value) - Inserting value into the stack:-


In a stack, push () is a function used to insert an element into the stack. In a stack, the new element is always
inserted at top position. Push function takes one integer value as parameter and inserts that value into the stack.
We can use the following steps to push an element on to the stack.
Step 1 - Check whether stack is FULL. (top == SIZE-1)
Step 2 - If it is FULL, then display "Stack is FULL!!! Insertion is not possible!!!" and terminate the function.
Step 3 - If it is NOT FULL, then increment top value by one (top++) and set stack[top] to value (stack[top] =
value).

Pop () - Delete a value from the stack: -


In a stack, pop () is a function used to delete an element from the stack. In a stack, the element is always
deleted from top position. Pop function does not take any value as parameter. We can use the following steps
to pop an element from the stack.
Step 1 - Check whether stack is EMPTY. (top == -1)
Step 2 - If it is EMPTY, then display "Stack is EMPTY!!! Deletion is not possible!!!" and terminate the
function.
Step 3 - If it is NOT EMPTY, then delete stack[top] and decrement top value by one (top--).

3
Display () - display the element of the stack:-
We can use the following steps to display the elements of a stack...
Step 1 - Check whether stack is EMPTY. (top == -1)
Step 2 - If it is EMPTY, then display "Stack is EMPTY!!!" and terminate the function.
Step 3 - If it is NOT EMPTY, then define a variable 'i' and initialize with top. Display stack[i] value and
decrement i value by one (i--).
Step 3 - Repeat above step until i value becomes '0'.

4
Program:

#include<stdio.h>
int stack[100],choice,n,top,x,i;
void push(void);
void pop(void);
void display(void);
int main()
{
//clrscr();
top=-1;
printf("\n Enter the size of STACK[MAX=100]:");
scanf("%d",&n);
printf("\n\t STACK OPERATIONS USING ARRAY");
printf("\n\t ");
printf("\n\t 1.PUSH\n\t 2.POP\n\t 3.DISPLAY\n\t 4.EXIT");
do
{
printf("\n Enter the Choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
display();
break;
}
case 4:
{
printf("\n\t EXIT POINT ");
break;
}
default:
{

5
printf ("\n\t Please Enter a Valid Choice(1/2/3/4)");
}

}
}
while(choice!=4);
return 0;
}
void push()
{
if(top>=n-1)
{
printf("\n\tSTACK is over flow");

}
else
{
printf(" Enter a value to be pushed:");
scanf("%d",&x);
top++;
stack[top]=x;
}
}
void pop()
{
if(top<=-1)
{
printf("\n\t Stack is under flow");
}
else
{
printf("\n\t The popped elements is %d",stack[top]);
top--;
}
}
void display()
{
if(top>=0)
{
printf("\n The elements in STACK \n");
for(i=top; i>=0; i--)
printf("\n%d",stack[i]);
printf("\n Press Next Choice");
}

6
else
{
printf("\n The STACK is empty");
}

7
Output:

8
Experiment No.2

Aim: Convert an Infix expression to Postfix expression using stack ADT.


Theory: Expression conversion is the most important application of stacks. Given an infix expression, it can
be converted to both postfix and prefix notations. Now, let us see how to convert an infix expression to postfix.

● Infix notation ( a operator b ): For example, a + b is an infix notation.


● Postfix notation ( a b operator ): a b + is the equivalent postfix notation of a + b.
The compiler scans the given expression either from left to right or from right to left.
Consider the below expression: a + b / c - d

● At first, the compiler scans the expression to evaluate the expression b / c, then scans the expression
again to add a to it. The result is then subtracted with d after another scan.
● This repeated scanning makes the process very inefficient and time consuming. It will be much easier
if the expression is converted to postfix (or prefix) before evaluation.
● The corresponding expression in postfix form is: abc/+d-. The postfix expressions can be easily
evaluated using a stack.

Steps to convert infix expression to postfix

1. Scan the given infix expression from left to right.


2. If the scanned character is an operand, then output it.
3. Else,

● If the precedence of the scanned operator is greater than the precedence of the operator in the top of
the stack(or the stack is empty or if the stack contains a ‘(‘ ), push it.
● Else, Pop all operators from the stack whose precedence is greater than or equal to that of the scanned
operator. Then, push the scanned operator to the top of the stack. (If you encounter parenthesis while
popping then stop there and push the scanned operator in the stack.)
4. If the scanned character is ‘(‘, push it to the stack.

5. If the scanned character is ‘)’, pop the stack and and output characters until ‘(‘ is encountered, and discard
both the parenthesis.

6. Repeat steps 2-5 until the infix expression is scanned completely.


7. Print the output.

8. Pop and output from the stack

9
Program Code:
#include<stdio.h>
#include<ctype.h>

char stack[100];
int top = -1;

void push(char x)
{
stack[++top] = x;

char pop()
{
if(top == -1)

return -1;
else

return stack[top--];

int priority(char x)
{
if(x == '(')

return 0;

if(x == '+' || x == '-')


return 1;
if(x == '*' || x == '/')
return 2;
return 0;

10
}

int main()

char exp[100];
char *e, x;
printf("Enter the Infix expression : ");
scanf("%s",exp);
printf("Equivalent Postfix expression : ");

e = exp;

while(*e != '\0')

{
if(isalnum(*e))
printf("%c ",*e);

else if(*e == '(')


push(*e);
else if(*e == ')')
{

while((x = pop()) != '(')

printf("%c ", x);


}

else

{
while(priority(stack[top]) >= priority(*e))
printf("%c ",pop());

push(*e);
}
e++;

}
11
while(top != -1)
{

printf("%c",pop());
}return 0;

12
Output:

13
Experiment No.3

Aim: Evaluate Postfix Expression using Stack ADT.


Theory: The compiler finds it convenient to evaluate an expression in its postfix form. The virtues of postfix
form include elimination of parentheses which signify priority of evaluation and the elimination of the need
to observe rules of hierarchy, precedence and associativity during evaluation of the expression

As Postfix expression is without parenthesis and can be evaluated as two operands and an operator at a time,
this becomes easier for the compiler and the computer to handle.

Evaluation rule of a Postfix Expression states:

1. While reading the expression from left to right, push the element in the stack if it is an operand.
2. Pop the two operands from the stack, if the element is an operator and then evaluate it.
3. Push back the result of the evaluation. Repeat it till the end of the expression.

Algorithm

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

i) A -> Top element

ii) B-> Next to Top element

iii) Evaluate B operator A

push B operator A onto Stack

5) Set result = pop

6) END

14
Program Code:
#include<stdio.h>
#include<ctype.h>
int stack[20];
int top = -1;
void push(int x)
{

stack[++top] = x;

int pop()
{

return stack[top--];
}
int main()

char exp[20];
char *e;

int n1,n2,n3,num;

printf("Enter the expression :: ");


scanf("%s",exp);
e = exp;
while(*e != '\0')

{
if(isdigit(*e))
{
num = *e - 48;

push(num);
}

else

15
{
n1 = pop();
n2 = pop();
switch(*e)

{
case '+':

n3 = n1 + n2;
break;
}

case '-':

n3 = n2 - n1;
break;
}
case '*':

n3 = n1 * n2;
break;
}

case '/':
{
n3 = n2 / n1;
break;

}
}
push(n3);

}
e++;

}
16
printf("\nThe result of expression %s = %d\n\n",exp,pop());
return 0;
}

17
Output:

18
Experiment No.4

Aim: Applications of Stack ADT


Theory: A stack is an Abstract Data Type (ADT), commonly used in most programming languages. It is
named stack as it behaves like a real-world stack, for example – a deck of cards or a pile of plates, etc. A real-
word stack allows operations at one end only. The abstract datatype is special kind of datatype, whose behavior
is defined by a set of values and set of operations. The keyword “Abstract” is used as we can use these
datatypes, we can perform different operations. But how those operations are working that is totally hidden
from the user. The ADT is made of with primitive datatypes, but operation logics are hidden.

Following are some of the important applications of a Stack data structure: -

1. Stacks can be used for expression evaluation.


2. Stacks can be used to check parenthesis matching in an expression.
3. Stacks can be used for Conversion from one form of expression to another.
4. Stacks can be used for Memory Management.
5. Stack data structures are used in backtracking problems.

1. Expression Evalution: -

Stack data structure is used for evaluating the given expression. For example, consider the following
expression

5 * ( 6 + 2 ) - 12 / 4
Since parenthesis has the highest precedence among the arithmetic operators, ( 6 +2 ) = 8 will be evaluated
first. Now, the expression becomes

5 * 8 - 12 / 4
* and / have equal precedence and their associativity is from left-to-right. So, start evaluating the expression
from left-to-right.

5 * 8 = 40 and 12 / 4 = 3
Now, the expression becomes

40 - 3
And the value returned after the subtraction operation is 37.

2. Parenthesis Matching: -
Given an expression, you have to find if the parenthesis is either correctly matched or not. For example,
consider the expression ( a + b ) * ( c + d ).

19
In the above expression, the opening and closing of the parenthesis are given properly and hence it is said to
be a correctly matched parenthesis expression. Whereas, the expression, (a + b * [c + d ) is not a valid
expression as the parenthesis are incorrectly given.

3. Expression Conversion: -
Converting one form of expressions to another is one of the important applications of stacks.

• Infix to prefix
• Infix to postfix
• Prefix to Infix
• Prefix to Postfix
• Postfix to Infix
• Postfix to Infix

4. Memory Management: -

The assignment of memory takes place in contiguous memory blocks. We call this stack memory allocation
because the assignment takes place in the function call stack. The size of the memory to be allocatedis known
to the compiler. When a function is called, its variables get memory allocated on the stack. When the function
call is completed, the memory for the variables is released. All this happens with the help of somepredefined
routines in the compiler. The user does not have to worry about memory allocation and release of stack
variables. The memory to be allocated to these variables is known to the compiler and when the functionis
called, the allocation is done and when the function terminates, the memory is released.

5. Backtracking Problems: -
The basic strategy we will use to solve this problem is to use backtracking. In this particular case,
backtracking means we will perform a safe move for a queen at the time we make the move. Later, however,
we find that we are stuck and there is no safe movement for the next Queen, whom we are trying to put on the
blackboard, so we have to go back.

This means we return to the queen's previous move, undo this step, and continue to search for a safe place to
place this queen.

We will use the stack to remember where we placed queens on the board, and if we need to make a backup,
the queen at the top of the stack will be popped, and we will use the position of that queen to resume the search
for next safe location.

20
Experiment No.5

Aim: Implement Priority Queue ADT using Array


Theory: A priority queue is a special type of queue in which each element is associated with a priority and
is served according to its priority. If elements with the same priority occur, they are served according to their
order in the queue.

Generally, the value of the element itself is considered for assigning the priority.

For example, The element with the highest value is considered as the highest priority element. However, in
other cases, we can assume the element with the lowest value as the highest priority element. In other cases,
we can set priorities according to our needs.

Implementation of Priority Queue:

Priority queue can be implemented using an array, a linked list, a heap data structure, or a binary search tree.
Among these data structures, heap data structure provides an efficient implementation of priority queues.

Hence, we will be using the heap data structure to implement the priority queue in this tutorial. A max-heap
is implement is in the following operations. If you want to learn more about it, please visit max-heap and
mean-heap.

A comparative analysis of different implementations of priority queue is given below.

Operations peek insert delete

Linked List O(1) O(n) O(1)

Binary Heap O(1) O(log n) O(log n)

Binary Search Tree O(1) O(log n) O(log n)

Priority Queue Operation: Basic operations of a priority queue are inserting, removing, and peeking
elements.

1. Inserting an Element into the Priority Queue:

Inserting an element into a priority queue (max-heap) is done by the following steps.

21
• Insert the new element at the end of the tree.

Insert an element at the end of the queue

• Heapify the tree.

Heapify after insertion

Algorithm for insertion of an element into priority queue (max-heap)

If there is no node,

create a newNode.

else (a node is already present)

22
insert the newNode at the end (last node from left to right.)

heapify the array

For Min Heap, the above algorithm is modified so that parentNode is always smaller than newNode.

2. Deleting an Element from the Priority Queue


Deleting an element from a priority queue (max-heap) is done as follows:.

Select the element to be deleted

• Swap it with the last element.

Swap with the last leaf node element

23
• Remove the last element.

Remove the last element leaf

• Heapify the tree.

Heapify the priority queue

Algorithm for deletion of an element in the priority queue (max-heap)

If nodeToBeDeleted is the leafNode

remove the node

Else swap nodeToBeDeleted with the lastLeafNode

24
remove noteToBeDeleted

heapify the array

For Min Heap, the above algorithm is modified so that the both childNodeare smaller than currentNode.

3. Peeking from the Priority Queue (Find max/min)

Peek operation returns the maximum element from Max Heap or minimum element from Min Heap
without deleting the node.

For both Max heap and Min Heap

return rootNode

4. Extract-Max/Min from the Priority Queue

Extract-Max returns the node with maximum value after removing it from a Max Heap whereas
Extract-Min returns the node with minimum value after removing it from Min Heap.

25
Program Code:
mport java.util.ArrayList;
class Heap {

// Function to heapify the tree


void heapify(ArrayList<Integer> hT, int i) {
int size = hT.size();

// Find the largest among root, left child and right child
int largest = i;

int l = 2 * i + 1;
int r = 2 * i + 2;
if (l < size && hT.get(l) > hT.get(largest))
largest = l;
if (r < size && hT.get(r) > hT.get(largest))
largest = r;

// Swap and continue heapifying if root is not largest

if (largest != i) {

int temp = hT.get(largest);


hT.set(largest, hT.get(i));
hT.set(i, temp);

heapify(hT, largest);
}

// Function to insert an element into the tree

void insert(ArrayList<Integer> hT, int newNum) {


int size = hT.size();
if (size == 0) {

26
hT.add(newNum);
} else {
hT.add(newNum);

for (int i = size / 2 - 1; i >= 0; i--) {


heapify(hT, i);
}

// Function to delete an element from the tree


void deleteNode(ArrayList<Integer> hT, int num) {
int size = hT.size();

int i;
for (i = 0; i < size; i++) {
if (num == hT.get(i))

break;

int temp = hT.get(i);


hT.set(i, hT.get(size - 1));

hT.set(size - 1, temp);

hT.remove(size - 1);
for (int j = size / 2 - 1; j >= 0; j--) {
heapify(hT, j);
}

// Print the tree

void printArray(ArrayList<Integer> array, int size) {


27
for (Integer i : array) {
System.out.print(i + " ");
}

System.out.println();
}

// Driver code
public static void main(String args[]) {

ArrayList<Integer> array = new ArrayList<Integer>();


int size = array.size();

Heap h = new Heap();


h.insert(array, 3);

h.insert(array, 4);

h.insert(array, 9);
h.insert(array, 5);
h.insert(array, 2);

System.out.println("Max-Heap array: ");

h.printArray(array, size);

h.deleteNode(array, 4);
System.out.println("After deleting an element: ");

h.printArray(array, size);
}

28
Output:

29
Experiment No.6

Aim: Implement Doubly Linked List ADT


Theory: Doubly linked list is a type of linked list in which each node apart from storing its data has two
links. The first link points to the previous node in the list and the second link points to the next node in the
list. The first node of the list has its previous link pointing to NULL similarly the last node of the list has its
next node pointing to NULL.
The two links help us to traverse the list in both backward and forward direction. But storing an extra link
requires some extra space.
Doubly linked list is a linked data structure that consists of a set of sequentially linked records called nodes.
Each node contains two fields, called links that are references to the previous and to the next node in the
sequence of nodes. The beginning and ending nodes’ previous and next links, respectively, point to some kind
of terminator, typically a sentinel node or null, to facilitate traversal of the list. Here we need to preform
insertion, deletion and display all the modes of given doubly linked list.

Doubly Linked List is a variation of Linked list in which navigation is possible in both ways, either forward
and backward easily as compared to Single Linked List. Following are the important terms to understand the
concept of doubly linked list.
• Link − Each link of a linked list can store a data called an element.
• Next − Each link of a linked list contains a link to the next link called Next.
• Prev − Each link of a linked list contains a link to the previous link called Prev.
• LinkedList − A Linked List contains the connection link to the first link called First and to the last
link called Last.

Doubly Linked List Representation

30
As per the above illustration, following are the important points to be considered.
• Doubly Linked List contains a link element called first and last.
• Each link carries a data field(s) and two link fields called next and prev.
• Each link is linked with its next link using its next link.
• Each link is linked with its previous link using its previous link.
• The last link carries a link as null to mark the end of the list.
Basic Operations
Following are the basic operations supported by a list.
• Insertion − Adds an element at the beginning of the list.
• Deletion − Deletes an element at the beginning of the list.
• Insert Last − Adds an element at the end of the list.
• Delete Last − Deletes an element from the end of the list.
• Insert After − Adds an element after an item of the list.
• Delete − Deletes an element from the list using the key.
• Display forward − Displays the complete list in a forward manner.
• Display backward − Displays the complete list in a backward manner.

31
Program Code:
#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <stdbool.h>

struct node {

int data;

int key;

struct node *next;

struct node *prev;

};

//this link always point to first Link

struct node *head = NULL;

//this link always point to last Link

struct node *last = NULL;

struct node *current = NULL;

//is list empty

bool isEmpty() {

return head == NULL;

int length() {

int length = 0;

struct node *current;

32
for(current = head; current != NULL; current = current->next){

length++;

return length;

//display the list in from first to last

void displayForward() {

//start from the beginning

struct node *ptr = head;

//navigate till the end of the list

printf("\n[ ");

while(ptr != NULL) {

printf("(%d,%d) ",ptr->key,ptr->data);

ptr = ptr->next;

printf(" ]");

//display the list from last to first

void displayBackward() {

//start from the last

struct node *ptr = last;

//navigate till the start of the list

printf("\n[ ");

33
while(ptr != NULL) {

//print data

printf("(%d,%d) ",ptr->key,ptr->data)

//move to next item

ptr = ptr ->prev;

//insert link at the first location

void insertFirst(int key, int data) {

//create a link

struct node *link = (struct node*) malloc(sizeof(struct node));

link->key = key;

link->data = data;

if(isEmpty()) {

//make it the last link

last = link;

} else {

//update first prev link

head->prev = link;

//point it to old first link

34
link->next = head;

//point first to new first link

head = link;

//insert link at the last location

void insertLast(int key, int data) {

//create a link

struct node *link = (struct node*) malloc(sizeof(struct node));

link->key = key;

link->data = data;

if(isEmpty()) {

//make it the last link

last = link;

} else {

//make link a new last link

last->next = link;

//mark old last node as prev of new link

link->prev = last;

35
//point last to new last node

last = link;

//delete first item

struct node* deleteFirst() {

//save reference to first link

struct node *tempLink = head;

//if only one link

if(head->next == NULL){

last = NULL;

} else {

head->next->prev = NULL;

head = head->next;

//return the deleted link

return tempLink;

//delete link at the last location

36
struct node* deleteLast() {

//save reference to last link

struct node *tempLink = last;

//if only one link

if(head->next == NULL) {

head = NULL;

} else {

last->prev->next = NULL;

last = last->prev;

//return the deleted link

return tempLink;

//delete a link with given key

struct node* delete(int key) {

//start from the first link

struct node* current = head;

37
struct node* previous = NULL;

//if list is empty

if(head == NULL) {

return NULL;

}
//navigate through list

while(current->key != key) {

//if it is last node

if(current->next == NULL) {

return NULL;

} else {

//store reference to current link

previous = current;

//move to next link

current = current->next;

//found a match, update the link

if(current == head) {

//change first to point to next link

head = head->next;

} else {

//bypass the current link

38
current->prev->next = current->next;

if(current == last) {

//change last to point to prev link

last = current->prev;

} else {

current->next->prev = current->prev;

return current;

bool insertAfter(int key, int newKey, int data) {

//start from the first link

struct node *current = head;

//if list is empty

if(head == NULL) {

return false;

//navigate through list

while(current->key != key) {

//if it is last node

if(current->next == NULL) {

return false;

39
} else {

//move to next link

current = current->next;

//create a link

struct node *newLink = (struct node*) malloc(sizeof(struct node));

newLink->key = newKey;

newLink->data = data;

if(current == last) {

newLink->next = NULL;

last = newLink;

} else {

newLink->next = current->next;

current->next->prev = newLink;

newLink->prev = current;

current->next = newLink;

return true;

void main() {

insertFirst(1,10);
40
insertFirst(2,20);

insertFirst(3,30);

insertFirst(4,1);

insertFirst(5,40);

insertFirst(6,56);

printf("\nList (First to Last): ");

displayForward();

printf("\n");

printf("\nList (Last to first): ");

displayBackward();

printf("\nList , after deleting first record: ");

deleteFirst();

displayForward();

printf("\nList , after deleting last record: ");

deleteLast();

displayForward();

printf("\nList , insert after key(4) : ");

insertAfter(4,7, 13);

displayForward();
41
printf("\nList , after delete key(4) : ");

delete(4);

displayForward();

42
Output:

List (First to Last):


[ (6,56) (5,40) (4,1) (3,30) (2,20) (1,10) ]

List (Last to first):


[ (1,10) (2,20) (3,30) (4,1) (5,40) (6,56) ]
List , after deleting first record:
[ (5,40) (4,1) (3,30) (2,20) (1,10) ]
List , after deleting last record:
[ (5,40) (4,1) (3,30) (2,20) ]
List , insert after key(4) :
[ (5,40) (4,1) (7,13) (3,30) (2,20) ]
List , after delete key(4) :
[ (5,40) (4,13) (3,30) (2,20) ]

43
Experiment No.7

Aim: implement stack/Linked Queue ADT using Linked List


Theory: Due to the drawbacks discussed in the previous section of this tutorial, the array implementation
cannot be used for the large scale applications where the queues are implemented. One of the alternative of
array implementation is linked list implementation of queue.

The storage requirement of linked representation of a queue with n elements is o(n) while the time requirement
for operations is o(1).

In a linked queue, each node of the queue consists of two parts i.e. data part and the link part. Each element
of the queue points to its immediate next element in the memory.

In the linked queue, there are two pointers maintained in the memory i.e. front pointer and rear pointer. The
front pointer contains the address of the starting element of the queue while the rear pointer contains the
address of the last element of the queue.

Insertion and deletions are performed at rear and front end respectively. If front and rear both are NULL, it
indicates that the queue is empty.

Operation on Linked Queue:

There are two basic operations which can be implemented on the linked queues. The operations are Insertion
and Deletion.

Insert operation:

The insert operation append the queue by adding an element to the end of the queue. The new element will be
the last element of the queue

44
Algorithm:
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

Deletion:

Deletion operation removes the element that is first inserted among all the queue elements. Firstly, we need to
check either the list is empty or not. The condition front == NULL becomes true if the list is empty, in thiscase
, we simply write underflow on the console and make exit.

Algorithm:

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

45
Program Code:

#include<stdio.h>

#include<stdlib.h>

struct node

int data;

struct node *next;

};

struct node *front;

struct node *rear;

void insert();

void delete();

void display();

void main ()

int choice;

while(choice != 4)

printf("\n*************************Main Menu*****************************\n");

printf("\n=================================================================\n");

printf("\n1.insert an element\n2.Delete an element\n3.Display the queue\n4.Exit\n");

printf("\nEnter your choice ?");

46
scanf("%d",& choice);

switch(choice)

case 1:

insert();

break;

case 2:

delete();

break;

case 3:

display();

break;

case 4:

exit(0);

break;

default:

printf("\nEnter valid choice??\n");

void insert()

struct node *ptr;

47
int item;

ptr = (struct node *) malloc (sizeof(struct node));

if(ptr == NULL)

printf("\nOVERFLOW\n");

return;

else

printf("\nEnter value?\n");

scanf("%d",&item);

ptr -> data = item;

if(front == NULL)

front = ptr;

rear = ptr;

front -> next = NULL;

rear -> next = NULL;

else

rear -> next = ptr;

48
rear = ptr;

rear->next = NULL;

void delete ()

struct node *ptr;

if(front == NULL)

printf("\nUNDERFLOW\n");

return;

else

ptr = front;

front = front -> next;

free(ptr);

void display()

struct node *ptr;

49
ptr = front;

if(front == NULL)

printf("\nEmpty queue\n");

else

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

while(ptr != NULL)

printf("\n%d\n",ptr -> data);

ptr = ptr -> next;

50
Output:

51
Experiment No.8

Aim: Implement Graph Traversal techniques: a) Depth First Search b) Breadth First Search
Theory: Graph traversal is a technique used for a searching vertex in a graph. The graph traversal is also
used to decide the order of vertices is visited in the search process. A graph traversal finds the edges to be used
in the search process without creating loops. That means using graph traversal we visit all the vertices ofthe
graph without getting into a looping path.

There are two graph traversal techniques and they are as follows...

1. DFS (Depth First Search)


2. BFS (Breadth First Search)

DFS (Depth First Search)

DFS traversal of a graph produces a spanning tree as the final result. Spanning Tree is a graph without loops.
We use Stack data structure with maximum size of total number of vertices in the graph to implement DFS
traversal.

We use the following steps to implement DFS traversal...

● Step 1 - Define a Stack of size total number of vertices in the graph.


● Step 2 - Select any vertex as starting point for traversal. Visit that vertex and push it onto the Stack.
● Step 3 - Visit any one of the non-visited adjacent vertices of a vertex which is at the top of stack and
push it onto the stack.
● Step 4 - Repeat step 3 until there is no new vertex to be visited from the vertex which is at the top of
the stack.
● Step 5 - When there is no new vertex to visit then use backtracking and pop one vertex from the stack.
● Step 6 - Repeat steps 3, 4 and 5 until the stack becomes Empty.
● Step 7 - When stack becomes Empty, then produce final spanning tree by removing unused edges from
the graph

BFS (Breadth First Search)

BFS traversal of a graph produces a spanning tree as a final result. Spanning Tree is a graph without loops.
We use Queue data structure with maximum size of total number of vertices in the graph to implement BFS
traversal.

We use the following steps to implement BFS traversal...

● Step 1 - Define a Queue of size total number of vertices in the graph.


● Step 2 - Select any vertex as starting point for traversal. Visit that vertex and insert it into the Queue.
● Step 3 - Visit all the non-visited adjacent vertices of the vertex which is at front of the Queue and insert
them into the Queue.
● Step 4 - When there is no new vertex to be visited from the vertex which is at front of the Queue then
delete that vertex.
52
● Step 5 - Repeat steps 3 and 4 until the queue becomes empty.
● Step 6 - When queue becomes empty, then produce final spanning tree by removing unused edges
from the graph

53
Program Code:
#include<stdio.h>

int q[20],top=-1,front=-1,rear=-1,a[20][20],vis[20],stack[20];
int delete();

void add(int item);


void bfs(int s,int n);

void dfs(int s,int n);


void push(int item);
int pop();

void main()
{

int n,i,s,ch,j;
char c,dummy;
printf("ENTER THE NUMBER VERTICES ");

scanf("%d",&n);
for(i=1;i<=n;i++)
{

for(j=1;j<=n;j++)

{
printf("ENTER 1 IF %d HAS A NODE WITH %d ELSE 0 ",i,j);

scanf("%d",&a[i][j]);
}
}
printf("THE ADJACENCY MATRIX IS\n");
for(i=1;i<=n;i++)

for(j=1;j<=n;j++)
{
printf(" %d",a[i][j]);

54
}
printf("\n");
}

do{

for(i=1;i<=n;i++)
vis[i]=0;

printf("\nMENU");
printf("\n1.B.F.S");
printf("\n2.D.F.S");

printf("\nENTER YOUR CHOICE");


scanf("%d",&ch);

printf("ENTER THE SOURCE VERTEX :");

scanf("%d",&s);
switch(ch)
{

case 1:bfs(s,n);
break;
case 2:

dfs(s,n);
break;

printf("DO U WANT TO CONTINUE(Y/N) ? ");


scanf("%c",&dummy);
scanf("%c",&c);

}while((c=='y')||(c=='Y'));
}

//**************BFS(breadth-first search) code**************//


void bfs(int s,int n)
{

int p,i;
55
add(s);
vis[s]=1;
p=delete();

if(p!=0)
printf(" %d",p);

while(p!=0)
{

for(i=1;i<=n;i++)
if((a[p][i]!=0)&&(vis[i]==0))

add(i);
vis[i]=1;

}
p=delete();

if(p!=0)
printf(" %d ",p);

for(i=1;i<=n;i++)
if(vis[i]==0)

bfs(i,n);

}
void add(int item)
{

if(rear==19)
printf("QUEUE FULL");
else

{
if(rear==-1)
{

q[++rear]=item;
56
front++;
}
else
q[++rear]=item;

}
}

int delete()

int k;
if((front>rear)||(front==-1))
return(0);

else

{
k=q[front++];
return(k);

//***************DFS(depth-first search) code******************//


void dfs(int s,int n)

int i,k;
push(s);
vis[s]=1;

k=pop();
if(k!=0)

printf(" %d ",k);
while(k!=0)
{
for(i=1;i<=n;i++)

if((a[k][i]!=0)&&(vis[i]==0))
57
{
push(i);
vis[i]=1;

}
k=pop();
if(k!=0)

printf(" %d ",k);

}
for(i=1;i<=n;i++)

if(vis[i]==0)

dfs(i,n);

}
void push(int item)
{

if(top==19){

printf("Stack overflow ");


else

stack[++top]=item;}

}
int pop()

int k;
if(top==-1)
return(0);

else
{

k=stack[top--];
return(k);

58
Output:

59
Experiment No.9

Aim: Applications of Binary Search Technique.


Theory: A binary search is a simplistic algorithm intended for finding the location of an item stored in a
sorted list. There are a few variations to the binary search in C program, such as testing for equality and less-
than at each step of the algorithm.
Binary search in C is an example of a simple process that can be used to dissolve complex problems. As such,
it is an important foundational concept that you will find in almost all the good books on the C programming
language.

Before giving you the code for establishing a binary search in C, let’s first understand how exactly the
algorithm works.

How Does it Work?


Binary search algorithm applies to a sorted array for searching an element. The search starts with comparing
the target element with the middle element of the array. If value matches then the position of the element is
returned.

In case the target element is less than the middle element (considering the array follows an ascending order)
of the array then the second half of the array is discarded and the search continues by dividing the first half.

The process is the same when the target element is greater than the middle element, only, in this case, the first
half of the array is discarded before continuing with the search. The iteration repeats until a match for the
target element is found.

Binary Search in C Program


The following code implements binary search in C programming language. Although it can only be used for
sorted arrays, it is fast in comparison to the linear search.

If the requirements ask for using binary search on an unsorted array, then it needs to be sorted first before
using the binary search algorithm on it. For doing so, you can make use of some sorting technique, such as the
bubble sort or the merge sort.

NOTE: - The code mentioned below assumes that the input numbers follow an ascending order!

The binary search is not restricted to searching for an element in a sorted sequence; if it were, the algorithm
would be considered trivial and uninteresting. An interesting application of the algorithm is binary search on
the result. For example, imagine that we want to find the minimum size needed for a square office that must
freely accommodate all the employees of a company. We can perform a binary search for that size rather than
sequentially checking all the possible sizes. We usually estimate the minimum and maximum sizes over which
we do a binary search. Next, we just check some middle value and the interval can be halved again, and so on.
That’s a lot of saved time.

60
Program Code:
#include<stdio.h>
int main()

{ int c, first, last, middle, n, search, array[100];


printf("Binary Search Techinque implementation\n\n\n");
printf("Enter number of elements:\n");

scanf("%d",&n);
printf("Enter %d integers:\n", n);
for (c = 0; c < n; c++)

scanf("%d",&array[c]);
printf("Enter the value to find:\n");
scanf("%d", &search);
first = 0;

last = n - 1;
middle = (first+last)/2;
while (first <= last) {

if (array[middle] < search)

first = middle + 1;
else if (array[middle] == search) {
printf("%d is present at index %d.\n", search, middle+1);
break;
} else
last = middle - 1;
middle = (first + last)/2;

}if (first > last)


printf("Not found! %d is not present in the list.\n", search);
return 0; }

61
Output:

62
PRACTICAL NO – 10

Aim : Implement Singly Linked List ADT.

Theory :

Linked List is a collection of interconnected nodes that together represent a sequence. Connected node
means if you have access of a node, then you can get access to the next nodes even though they are not
located in consecutive memory locations.

For singly linked list, you can traverse the list only in one direction. The diagram below shows an example
of a singly linked list.

CODE :

#include <stdio.h>
#include <stdlib.h>
struct node
{
int val;
struct node *next;
};
/*Print the linked list*/
void print_list(struct node *head)
{
printf("H->");
while(head)
{
printf("%d->", head->val);
head = head->next;
}
printf("|||\n");
}
/*Insert an element at the front of the list*/
void insert_front(struct node **head, int value)
{
struct node * new_node = NULL;
/*Allocating memory for the new node*/
new_node = (struct node *)malloc(sizeof(struct node)); if (new_node == NULL)
{
printf("Failed to insert element. Out of memory");
}
new_node->val
/*Pointing the new node to where head is currently pointing to*/
new_node->next = *head;
/*Pointing head to new node.*/
*head = new_node;
}
void main()
{ int count = 0, i, val;
struct node * head = NULL;
printf("Enter number of elements: ");
scanf("%d", &count);
for (i = 0; i < count; i++)
{
63
printf("Enter %dth element: ", i);
scanf("%d", &val);
insert_front(&head, val);
}
printf("Linked List: ");
print_list(head);
}

OUTPUT –

64
64

You might also like