Data Structure Lab Manual
Data Structure Lab Manual
BHUSAWAL
DEPARTMENT OF COMPUTER SCIENCE & ENGINEERING
___________________________________________________________________________
List of Practical
1
PRACTICAL NO. 1
Aim: - Performing simple operations like push, pop and display with respect to stack.
Theory:-
Stack is an ordered collection of items in which insertion and deletion are made at one end
called the top. The restriction on stack is last element to be inserted into the stack will be the first to be
removed. Stack is also referred as LIFO. A stack can have any abstract data type as an element, but is
characterized by only three fundamental operations: push, pop and stack top.
PUSH OPERATION: The push operation adds a new item to the top of the stack, or initializes the
stack if it is empty. If the stack is full and does not contain enough space to accept the given item, the
stack is then considered to be in an overflow state.
POP OPERATION: The pop operation removes an item from the top of the stack. A pop either
reveals previously concealed items, or results in an empty stack, but if the stack is empty then it goes
into underflow state.
A show operation displays the elements of stack starting from top of the stack and decreasing upto 0
th position of the stack. The underflow condition is executed if there are no elements into the stack.
Stack is used at various places such as for expression evaluation, parenthesis matching, recursion,
function calls etc.
Algorithm: -
1. Start
2. Enter the maximum number of elements of the stack (n). Set top= -1
3. Print Menu
a. Push
b. Pop
2
c. Show
d. Exit
5. If choice =1 /*Insertion*/
Else
top=top+1
stack[top]=item to be inserted
6. If choice =2 /*Deletion*/
else
item=stack[top]
top=top-1
7. If choice =3 /*Show*/
If top <0
Else
Set i=top
3
Repeat While i> =0
b) Decrement i
8. If choice = 4 /*Exit*/
Exit
9. Stop.
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
4
PRACTICAL NO. 2
Aim : Performing simple conversions of given infix expression into postfix expression
Theory:-
The algebraic expression can be represented in three ways depending on relative position of
operator with respect to two operands.
Infix Expression : Any expression in the standard form like "2*3-4/5" is an Infix (Inorder) expression.
Postfix Expression : The Postfix (Postorder) form of the above expression is "23*45/-".
Infix to Postfix Conversion : In normal algebra we use the infix notation like a+b*c. The
corresponding postfix notation is abc*+. The algorithm for the conversion is as follows :
Algorithm: -
1. Start
5
5. Check whether symbol is operand ,operator or left-right parenthesis.
6. If the stack is empty or contains a left parenthesis on top, push the incoming operator onto the
stack.
8. If the incoming symbol is a right parenthesis, pop the stack and print the operators until you see
a left parenthesis. Discard the pair of parentheses
9. If the incoming symbol has higher precedence than the top of the stack, push it on the stack
10. If the incoming symbol has equal precedence with the top of the stack, use association. If the
association is left to right, pop and print the top of the stack and then push the incoming
operator. If the association is right to left, push the incoming operator.
11. If the incoming symbol has lower precedence than the symbol on the top of the stack, pop the
stack and print the top operator. Then test the incoming operator against the new top of stack.
12. At the end of the expression, pop and print all operators on the stack.
14. Stop.
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
6
PRACTICAL NO. 3
Aim : - Performing simple operations like insertion and deletion of an element into the circular queue.
Theory:-
A circular queue is one in which the insertion of new element is done at the very first location
of the queue if the last location of the queue is full. Suppose if we have a Queue of n elements then
after adding the element at the last index i.e. (n-1) th , as queue is starting with 0 index, the next
element will be inserted at the very first location of the queue which was not possible in the simple
linear queue. That's why linear queue leads to wastage of the memory, and this flaw of linear queue is
overcome by circular queue. While dealing with the circular queue we will use the following
assumptions: Front will always be pointing to the first element of the queue.
Graphical representation of a circular queue can be done as follows in which last element is connected
to first element in a form of loop or ring.
In a circular queue, after rear reaches the end of the queue, it can be reset to first position. This helps in
refilling the empty spaces in between. The difficulty of managing front and rear in an array-based non-
circular queue can be overcome if we treat the queue position with index 0 as if it comes after the last
position, i.e., we treat the queue as circular. Note that we use the same array declaration of the queue.
7
In Queue, each time a new element is inserted into the queue, the value of rear is incremented by one
i.e. Rear = (Rear + 1). Each time when an existing element is deleted from the queue, the value of rear
is incremented by one i.e. Front = (Front + 1). If rear = n-1 then next rear=0 else rear=rear+1 this can
be achieved by using modular operation as rear= (rear+1)% n. Similarly for deletion front should be
incremented one position clockwise i.e. front=(front+1)% n.
Algorithm: -
1. Start
2. Enter the maximum elements of circular queue & Set front =rear =0
3. Print Menu
a. Insertion
b. Deletion
c. Show
d. Exit
4. If choice = 1 /*Insertion*/
Check if front=(rear+1)% n
Else
rear=(rear+1)%n
cqueue[rear]=item to beinserted
5. If choice = 2 /*Deletion*/
Check if front=rear
8
Print cqueue is empty
Else
front=(front+1)% n
item = cqueue[front]
6. If choice= 3 /*Show*/
If front=rear
Else If rear<front
Set i=front
Set i=0
Else
Set i=front
9
7. If choice = 4 /*Exit*/
Exit
8. Stop.
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
10
PRACTICAL NO. 4
Aim : Implement a singly linked list and perform various operations such as insert ,delete and show.
Theory:
Singly Linked Lists are a type of data structure. It is a type of list. In a singly linked list each
node in the list stores the contents of the node and a pointer or reference to the next node in the list. It
does not store any pointer or reference to the previous node. It is called a singly linked list because
each node only has a single link to another node. Here is the pictorial view of singly linked list:
Linked list is collection of Nodes where each node is divided into 2 parts. The first part is say INFO,
which contains actually Information or data part,the second part is called as NEXT, which contains
address of next node.
Various operations on Linked list are:
1. To Insert At Beginning
2. To Insert At End
3. To Delete From Beginning
4. To Delete From End
5. Show elements in Linked List.
11
A) TO INSERT AT BEGINNING
INSERT_ BEG (INFO,START,ITEM,NEXT,MOVE,TEMP)
1.[If Link List is Empty?]
If START =NULL then
Set START := TEMP and Return
2. [If Link list is not empty?]
Else
{
[NEXT]TEMP=START
START=TEMP
} and return.
B) TO INSERT AT END
INSERT_END (INFO,START,ITEM,NEXT,MOVE,TEMP)
1.[If Link List is Empty?]
If START =NULL then
Set START := TEMP and Return
2. [If Link list is not empty?]
Else
{
Set MOVE := START
Repeat while NEXT[MOVE]!=NULL
Set MOVE:=[NEXT]MOVE
[end of loop]
[NEXT]MOVE=TEMP
} and return.
12
{
Print([INFO]START)
13
Set START=NULL
}
Else
{
Set ITEM =[INFO]START
START=[NEXT]START
Print (ITEM)
} and return.
D) TO DELETE FROM END
DEL_END (INFO,START,ITEM,NEXT,MOVE,,BACK,TEMP)
1.[If Link List is Empty?]
If START =NULL then
print (“List is Empty”)and Return
2. [If Link list is not empty?]
Else If [NEXT]START=NULL
{
Print([INFO]START)
Set START=NULL
}
Else
{
Set MOVE := START
Repeat while NEXT[MOVE]!=NULL
{
Set BACK=MOVE
Set MOVE:=[NEXT]MOVE
}[end of loop]
ITEM=[INFO]MOVE
[NEXT]BACK :=NULL
Print(ITEM)
} and return.
14
E )To Show elements in Linked List
SHOW(START,INFO,NEXT,MOVE)
1.[If Link List is Empty?]
If START =NULL then
Print (“List is Empty..”)
2. [If Link list is not empty?]
Else
{
Set MOVE := START
Repeat while [MOVE]!=NULL
{
Print([INFO] MOVE)
Set MOVE:=[NEXT]MOVE
}[end of loop]
} and return.
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
15
PRACTICAL NO. 5
Aim: - Creation of hash Table and handle the collision using linear probing without replacement.
Theory:-
Hash table or hash map is a data structure that uses a hash function to map identifying values,
known as keys (e.g., a person's name), to their associated values (e.g., their telephone number). Thus, a
hash table implements an associative array. The hash function is used to transform the key into the
index (the hash) of an array element (the slot or bucket) where the corresponding value is to be sought.
Ideally, the hash function should map each possible key to a unique slot index, but this ideal is rarely
achievable in practice (unless the hash keys are fixed; i.e. new entries are never added to the table after
it is created). Instead, most hash table designs assume that hash collisions—different keys that map to
the same hash value—will occur and must be accommodated in some way. If two different key hashes
to the same record number then there will be collision of data & we will have to find some other
position to store the record. To resolve this collision there are different ways:
In Open addressing Collison can be resolve by using Linear Probing, Quadratic Probing or Double
Hashing. Linear Probing is resolving a hash collision by sequentially searching a hash table beginning
at the location returned by the hash function. It is Open addressing mode of collision resolution. Hash
table can be implemented using an array. The program stores the first element that generates a specific
array index using hash function. If number is already present at that index position then find next empty
position and then insert the value.
In this case, hash table is implemented using an array. The program stores the first element that
generates a specific array index at that index. For example, if the hash function generates 79, then you
16
use array index 79 to store the element. When the hash function generates the key 79 again, the
program begins a sequential search starting at location 79, looking for the next available spot. The
second element whose key was transformed by hash function into 79 will be stored at the location 80,
the third at 81 and so on. Of course, if 80 and 81 are already occupied, the elements will be stored
farther away from the location generated by hash function.
17
num.
5 Check whether any data is available in the corresponding position.
18
6 If no data present
i) Enter the data in the calculated position.
Else
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
19
PRACTICAL NO. 6
Theory:-
Insertion sort is a simple sorting algorithm that builds the final sorted array (or list) one item at
a time. It is much less efficient on large lists than more advanced algorithms but have certain
advantages. An example of an insertion sort occurs in everyday life while playing cards. To sort the
cards in your hand you extract a card, shift the remaining cards, and then insert the extracted card in the
correct place. This process is repeated until all the cards are in the correct sequence. Both average and
worst-case time is O(n2).The steps to be followed in insertion sort can be given as:
Step 1: The second element of an array is compared with the elements that appears before it (only first
element in this case). If the second element is smaller than first element, second element is inserted in
the position of first element. After first step, first two elements of an array will be sorted.
Step 2: The third element of an array is compared with the elements that appears before it (first and
second element). If third element is smaller than first element, it is inserted in the position of first
element. If third element is larger than first element but, smaller than second element, it is inserted in
the position of second element. If third element is larger than both the elements, it is kept in the
position as it is. After second step, first three elements of an array will be sorted.
Step 3: Similary, the fourth element of an array is compared with the elements that appears before it
(first, second and third element) and the same procedure is applied and that element is inserted in the
proper position. After third step, first four elements of an array will be sorted.
If there are n elements to be sorted. Then, this procedure is repeated n-1 times to get sorted list of array,
20
due to which this algorithm is less efficient for large data.
Algorithm:
INSERTION_SORT (A)
1. for j ← 1 to n
2. do key ← A[j]
3. {Put A[j] into the sorted sequence A[1 . . j − 1]}
4. i←j−1
5. while i > 0 and A[i] > key
6. do A[i +1] ← A[i]
7. i←i−1
8. A[i + 1] ← key
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
21
PRACTICAL NO. 7
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.
Relation between BFS for Graph and Tree traversal:
Breadth-First Traversal (or Search) for a graph is similar to the Breadth-First Traversal of a tree.
The only catch here is, that, unlike trees, graphs may contain cycles, so we may come to the same node
again. To avoid processing a node more than once, we divide the vertices into two categories:
Visited and
Not visited.
A boolean visited array is used to mark the visited vertices. For simplicity, it is assumed that all
vertices are reachable from the starting vertex. BFS uses a queue data structure for traversal.
How does BFS work?
Starting from the root, all the nodes at a particular level are visited first and then the nodes of the next
level are traversed till all the nodes are visited.
To do this a queue is used. All the adjacent unvisited nodes of the current level are pushed into the
queue and the nodes of the current level are marked visited and popped from the queue.
Illustration:
Let us understand the working of the algorithm with the help of the following example.
22
Queue and visited arrays are empty initially.
Step 3: Remove node 0 from the front of queue and visit the unvisited neighbours and push them into
queue.
23
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.
24
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.
25
Remove node 4 from the front of queue and visit the unvisited neighbours and push them into queue.
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
Program:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#define MAX_VERTICES 50
// No. of vertices
int V;
bool adj[MAX_VERTICES][MAX_VERTICES];
} Graph;
// Constructor
Graph* Graph_create(int V)
26
{
Graph* g = malloc(sizeof(Graph));
g->V = V;
return g;
}
// Destructor
void Graph_destroy(Graph* g) { free(g); }
// Driver code
int main()
{
// Create a graph
Graph* g = Graph_create(4);
Graph_addEdge(g, 0, 1);
Graph_addEdge(g, 0, 2);
Graph_addEdge(g, 1, 2);
Graph_addEdge(g, 2, 0);
Graph_addEdge(g, 2, 3);
Graph_addEdge(g, 3, 3);
return 0;
}
Output
Following is Breadth First Traversal (starting from vertex 2)
2031
Time Complexity: O(V+E), where V is the number of nodes and E is the number of edges.
Auxiliary Space: O(V)
28
PRACTICAL NO. 8
29
Output : 0 1 3 4 5 6 2
Explanation: The traversal starts from 0 and follows the following path 0-1, 1-3, 1-4, 1-5, 1-6, 6-2.
Input: V = 1, E = 0
Output: 0
Explanation: There is no other vertex than 0 itself.
0 1 1 0 0 0 0
30
1 0 0 1 1 1 1
1 0 0 0 0 0 1
0 1 0 0 0 0 0
0 1 0 0 0 0 0
0 1 0 0 0 0 0
0 1 1 0 0 0 0
Conclusion: -
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------------------------------
31