Data Structure Notes
Data Structure Notes
LAB MANUAL
Branch : - CSE
Year : - 2nd
Semester : - 3rd
MISSION
To offer diverse academic programs at undergraduate, postgraduate, and doctorate levels that are in
line with the current trends in Computer Science and Engineering.
To provide the state-of-the-art infrastructure for teaching, learning and research.
To facilitate collaborations with other universities, industry and research labs.
PEO1 To produce graduates who have strong foundation of knowledge and skills in the field of
computer science and engineering.
PEO3 To produce graduates who can provide solutions to challenging problems in their profession
by applying computer engineering theory and practices.
PEO4 To produce graduates who can provide leadership and are effective in multidisciplinary
environment.
PROGRAM SPECIFIC OUTCOMES (PSO’s)
Ability to understand the principles and working of computer systems. Students
PSO 1 have a sound knowledge about the hardware and software aspects of computer
systems.
Ability to design and develop computer programs and understand the structure and
PSO 2 development methodologies of software systems.
Ability to apply their skills in the field of algorithms, networking, web design, cloud
PSO 3 computing and data analytics.
Ability to apply knowledge to provide innovative novel solutions to existing
PSO 4 problem and identify research gaps.
Course Objectives
1. To comprehend the basics of Data Structure, their Managements and Operations such as array, string
manipulations and various operations over different kinds of linked lists.
2. To learn stack & queue data structure and various applications based on the phenomenon of recursion,
Polish notations and polish conversions, priority Queue & its Programming implementation.
3. Understanding the tree data structure and its various types & applications to develop the efficient
solutions and fine tune the complexity of solutions through its Programming implementation.
4. To study the various sorting and searching techniques and various algorithmic approaches, know hashing
and collision resolving techniques & its Programming implementation.
5. To Understand and implement the hierarchical data structure such as Graph and its various traversal
algorithms, concept of file organization and record handling.
Course Outcome
After undergoing this laboratory module, the participant should be able to:
1. Recall and understand the basics of data structures, their programming implementations, and
foundational concepts for developing better solutions using Array and Linked list. Able to implement
the stack, Queue and their applications.
2. Apply, analyze, and evaluate stack and queue data structures, understand the phenomenon of recursion,
and implement various applications based on these principles. Able to implement different Sorting and
Search methods.
3. Develop and assess solutions using tree data structures, applying recursive approaches to enhance the
efficacy of the solution to the complex problems.
4. Apply, analyze, and evaluate different searching and sorting algorithms, assessing their performance
to ensure optimized data handling.
5. Understand, create, and, implement solutions for graph-based data structures & file organization
techniques to develop efficient solutions using non-linear data structure approaches.
CERTIFICATE
2
Overview of Array and Sparse Matrix
In C programming, one of the frequently arising problems is to handle similar types of data. For example: If
the user wants to store marks of 100 students. This can be done by creating 100 variables individually but,
this process is rather tedious and impracticable. This type of problem can be handled in C programming using
arrays.
An array is a sequence of data item of homogeneous value (same type). Arrays are of two types:
One-dimensional arrays
Multidimensional Arrays
data_type array_name[array_size];
For example:
int age[5];
Here, the name of array is age. The size of array is 5, i.e., there are 5 items elements) of array age.
All elements in an array are of the same type (int, in this case).
Initialization of one-dimensional array:
Arrays can be initialized at declaration time in this source code as:
Sparse Matrix: -
In numerical analysis, a sparse matrix is a matrix populated primarily with zeros as elements of the table.
By contrast, if a larger number of elements differ from zero, then it is common to refer to the matrix as a
dense matrix. The fraction of zero elements (non-zero elements) in a matrix is called the sparsity (density).
Conceptually, sparsity corresponds to systems which are loosely coupled. Consider a line of balls connected
by springs from one to the next; this is a s parse system. By contrast, if the same line of balls had springs
connecting each ball to all other balls, the system would be represented by a dense matrix. The concept of
sparsity is useful in combinatory and application areas such as network theory, which have a low density of
significant data or connections.
3
EXPERIMENT NO 1.1
OBJECTIVE
#include<stdio.h>
void main()
{
int a[4],i,pos,data;
printf("Enter the number");
for(i=0;i<3;i++)
{
scanf("%d",&a[i]);
}
printf("Enter the position");
scanf("%d",&pos);
printf("Enter the Data");
scanf("%d",&data);
for(i=2;i>=pos;i--)
{
a[i+1]=a[i];
}
a[pos]=data;
printf("The Final Array is\n");
for(i=0;i<4;i++)
{
printf("%d\t",a[i]);
}
}
Output:
Enter the Number: 7 6 5 2
3
12
The Final Array is:
7 6 5 12 2
4
EXPERIMENT NO 1.2
OBJECTIVE
#include<stdio.h>
void main()
{
int a[5],i,pos,data;
printf("Enter the number");
for(i=0;i<4;i++)
{
scanf("%d",&a[i]);
}
printf("Enter the position");
scanf("%d",&pos);
for(i=pos;i<4;i++)
{
a[i]=a[i+1];
}
printf("The Final Array is\n");
for(i=0;i<3;i++)
{
printf("%d\t",a[i]);
}
}
Output:
Enter the Number: 7 6 5 2
2
The Final Array is:
762
5
EXPERIMENT NO 1.3
OBJECTIVE
#include <stdio.h>
int binarySearch(int arr[], int left, int right, int x)
{
while (left <= right)
{
int mid = left + (right - left) / 2;
if (arr[mid] == x)
return mid;
if (arr[mid] < x)
left = mid + 1;
else
right = mid - 1;
}
return -1;
}
int main()
{
int arr[] = {2, 4, 6, 8, 10, 12, 14, 16, 18, 20};
int n= sizeof(arr) / sizeof(arr[0]);
int x = 14;
int result = binarySearch(arr, 0, n - 1, x);
if (result == -1)
printf("Element not found");
else
printf("Element found at index %d", result);
return 0;
}
Output:
Element found at index: 6
6
Overview of Sorting
Sorting: -
Sorting is any process of arranging items according to a certain sequence or in different sets, and therefore, it
has two common, yet distinct meanings:
Ordering: arranging items ofthe same kind, class or nature, in some ordered sequence,
Categorizing: grouping and labeling items with similar properties together (by sorts).
Bubble Sort: -
Bubble sort, sometimes referred to as sinking sort, is a simple sorting algorithm that works by repeatedly
stepping through the list to be sorted, comparing each pair of adjacent items and swapping them if they are in
the wrong order. The pass through the list is repeated until no swaps are needed, which indicates that the list
is sorted. The algorithm gets its name from the way smaller elements "bubble" to the top of the list. Because it
only uses comparisons to operate on elements, it is a comparison sort. Although the algorithm is simple, most
of the other sorting algorithms are more efficient for large lists.
Selection Sort: -
Selection sort is a sorting algorithm, specifically an in-place comparison sort. It has O (n2) time complexity,
making it inefficient on large lists, and generally performs worse than the similar insertion sort. Selection sort
is noted for its simplicity, and it has performance advantages over more complicated algorithms in certain
situations, particularly where auxiliary memory is limited.
The algorithm divides the input list into two parts: the sub list of items already sorted, which is built up from
left to right at the front (left) of the list, and the sub list of items remaining to be sorted that occupy the rest
of the list. Initially, the sorted sub list is empty and the unsorted sub list is the entire input list. The algorithm
proceeds by finding the smallest (or largest, depending on sorting order) element in the unsorted sub list,
exchanging it with the leftmost unsorted element (putting it in sorted order), and moving the sub list boundaries
one element to the right.
Insertion Sort: -
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 such as quick sort, heap sort, or merge sort.
However, insertion sort provides several advantages: Simple implementation Efficient for (quite) small data
sets Adaptive (i.e., efficient) for data sets that are already substantially sorted: the time complexity is O (n +
d), where d is the number of inversions.
More efficient in practice than most other simple quadratic (i.e., O(n2)) algorithms such as selection sort or
bubble sort; the best case (nearly sorted input) is O(n) stable; i.e., does not change the relative order of elements
with equal keys in-place; i.e., only requires a constant amount O(1) of additional memory space; i.e., can sort
a list as it receives it When humans manually sort something (for example, a deck of playing cards), most use
a method that is similar to insertion sort.
7
Quick Sort: -
Quick sort, or partition-exchange sort, is a sorting algorithm developed by Tony Hoare that, on average, makes
O(nlogn) comparisons to sort n items. In the worst case, it makes O (n2) comparisons, though this behavior is
rare. Quick sort is often faster in practice than other O(nlogn) algorithms. Additionally, quick sort sequential
and localized memory references work well with a cache. Quick sort is a comparison sort and, in efficient
implementations, is not a stable sort. Quick sort can be implemented with an in-place partitioning, so the entire
sort can be done with only O(logn) additional space used by the stack during the recursion.
Merge Sort: -
In computer science, merge sort (also commonly spelled merge sort) is an O (n log n) comparison-based sorting
algorithm. Most implementations produce a stable sort, which means that the implementation preserves the
input order of equal elements in the sorted output. Merge sort is a divide and conquer algorithm that was
invented by John von Neumann in 1945.
8
EXPERIMENT NO 2.1
OBJECTIVE
Output:
Enter number of elements:
5
56031
Sorted list in ascending order:
01356
9
EXPERIMENT NO 2.2
OBJECTIVE
#include <stdio.h>
int main()
{
int array[100], n, c, d, position, swap;
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]);
for (c = 0; c < (n - 1); c++)
{
position = c;
for (d = c + 1; d < n; d++)
{
if (array[position] > array[d])
position = d;
}
if (position! =c)
{
swap = array[c];
array[c] = array[position];
array[position] = swap;
}
}
printf("Sorted list in ascending order:\n");
for (c = 0; c < n; c++)
printf("%d\n", array[c]);
return 0;
}
Output:
Enter number of elements:
5
56031
Sorted list in ascending order:
01356
10
EXPERIMENT NO 2.3
OBJECTIVE
#include <stdio.h>
int main()
{
int n, array[1000], c, d, t;
printf("Enter number of elements\n");
scanf("%d", &n);
printf("Enter %d integers\n", n);
for (c = 0; c < n; c++)
{
scanf("%d", &array[c]);
}
for (c = 1; c <= n - 1; c++)
{
d = c;
while (d > 0 && array[d] < array[d-1])
{
t=array[d];
array[d]=array[d-1];
array[d-1] =t;
d--;
}
}
printf("Sorted list in ascending order:\n");
for (c = 0; c <= n - 1; c++)
{
printf("%d\n", array[c]);
}
return 0;
}
Output:
Enter number of elements:
5
12 5 4 -2 10
Sorted list in ascending order:
-2 4 5 10 12
11
EXPERIMENT NO 2.4
OBJECTIVE
12
}
}
Output:
Enter size of the array: 5
15 2 0 3 1
Sorted elements:
0 1 2 3 15
13
EXPERIMENT NO 2.5
OBJECTIVE
if(arr[l]<=arr[m])
{
temp[i]=arr[l];
l++;
}
14
else
{
temp[i]=arr[m];
m++;
}
i++;
}
if(l>mid)
{
for(k=m;k<=high;k++)
{
temp[i]=arr[k];
i++;
}
}
else
{
for(k=l;k<=mid;k++)
{
temp[i]=arr[k];
i++;
}
}
for(k=low;k<=high;k++)
{
arr[k]=temp[k];
}
}
Output:
Enter the total number of elements:
8
Enter the elements which to be sort:
12
3
2
1
4
7
-3
9
After merge sorting elements are:
-3 1 2 3 4 7 9 12
15
EXPERIMENT NO 2.6
OBJECTIVE
Write a program to Implement Heap Sort Using Array.
#include<stdio.h>
#include<conio.h>
void swap(int *x,int *y)
{
int temp;
temp=*x;
*x = *y;
*y = temp;
}
void heapsort(int a[],int n)
{
int i,s,f;
for(i=1;i< n;++i)
{
s=i;
f=(s-1)/2;
while( a[f]< a[s])
{
swap(&a[f],&a[s]);
s=f;
if(s==0)
break;
f=(s-1)/2;
}
}
for(i=n-1;i>=1;--i)
{
swap(&a[0],&a[i]);
f=0;
s=1;
if(i==1)
break;
if(i>2)
if (a [2]>a [1])
s=2;
while(a[f]< a[s])
{
swap(&a[f], &a[s]);
f=s;
s=2*f+1;
if(i>s+)
if(a[s+1]>a[s])
s=s+1;
16
if (s>=i)
break;
}
}
}
void main()
{
int a[100],n,i;
clrscr();
printf("\t\tHEAP SORT\n");
printf("\nEnter The Number of Elements\t: ");
scanf("%d",&n);
printf("\nEnter Elements\n");
for(i=0;i< n;++i)
scanf("%d",&a[i]);
heapsort(a,n);
printf("\n\t\t\tSorted List\n");
for(i=0;i< n;++i)
printf("\t%d",a[i]);
getche();
}
Output:
Enter The Number of Elements: 5
Enter Elements:
11 10 5 8 4
Sorted List:
4 5 8 10 11
17
Overview of Linked List
Linked List: -
A linked list is a data structure consisting of a group of nodes which together represent a sequence. Under the
simplest form, each node is composed of a data and a reference (in other words, a link) to the next node in the
sequence; more complex variants add additional links. This structure allows for efficient insertion or removal
of elements from any position in the sequence.
A linked list whose nodes contain two fields: an integer value and a link to the next node. The last node is
linked to a terminator used to signify the end of the list.
Linked lists are among the simplest and most common data structures. They can be used to implement several
other common abstract data types, including lists (the abstract data type), stack, queues, associative arrays, and
S-expressions, though it is not uncommon to implement the other data structures directly without using a
list as the basis of implementation.
The principal benefit of a linked list over a conventional array is that the list elements can easily be inserted
or removed without reallocation or reorganization of the entire structure because the data items need not be
stored contiguously in memory or on disk. Linked lists allow insertion and removal of nodes at any point in
the list, and can do so with a constant number of operations if the link previous to the link being added or
removed is maintained during list traversal.
On the other hand, simple linked lists by themselves do not allow random access to the data, or any form of
efficient indexing. Thus, many basic operations— such as obtaining the last node of the list (assuming that the
last node is not maintained as separate node reference in the list structure), or finding a node that contains a
given datum, or locating the place where a new node should be inserted— may require scanning most or all
of the list elements. The advantages and disadvantages of using linked lists are as follows: -
Advantages:
1. Linked lists are a dynamic data structure, allocating the needed memory when the program is initiated.
2. Insertion and deletion node operations are easily implemented in a linked list.
3. Linear data structures such as stacks and queues are easily executed with a linked list. They can
reduce access time and may expand in real time without memory overhead.
Disadvantages:
1. They have a tendency to waste memory due to pointers requiring extra storage space. Nodes in a
linked list must be read in order from the beginning as linked lists are inherently sequential access.
a. Nodes are stored in contiguously, greatly increasing the time required to access
individual elements within the list.
b. Difficulties arise in linked lists when it comes to reverse traversing. Singly linked lists are
extremely difficult to navigate backwards, and while doubly linked lists are somewhat easier
to read, memory is wasted in allocating space for a back pointer.
18
Double Linked List: -
In a doubly linked list, each node contains, besides the next- node link, a second link field pointing to the
previous node in the sequence. The two links may be called forward(s) and backwards, or next and prev
(previous).
A doubly linked list whose nodes contain three fields: an integer value, the link forward to the next node,
and the link backward to the previous node.
A technique known as XOR-linking allows a doubly linked list to be implemented using a single link field
in each node. However, this technique requires the ability to do bit operations on addresses, and therefore
may not be available in some high-level languages.
In the last node of a list, the link field often contains a null reference, a special value used to indicate the lack
of further nodes. A less common convention is to make it point to the first node of the list; in that case the
list is said to be 'circular' or 'circularly linked'; otherwise, it is said to be 'open' or 'linear'.
19
EXPERIMENT NO 3.1
OBJECTIVE
#include<stdio.h>
#include<conio.h>
#include<malloc.h>
struct node
{
int info;
struct node *link;
}*start;
void main()
{
int ch,n,m,pos,i;
clrscr();
start=NULL;
while(1)
{
printf("\n 1. Create");
printf("\n 2. Insertatbeg");
printf("\n 3. Insertatmiddle");
printf("\n 4. Delete");
printf("\n 5. Display");
printf("\n 6. Exit");
printf("\n Enter the choice:-");
scanf("%d",&ch);
switch(ch)
{
case 1: printf("\n how many nodes u want to insert:-");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("\n Enter the data:-");
scanf("%d",&m);
create(m);
}
break;
case 2:printf("enter the elements:-");
scanf("%d",&m);
addatbeg(m);
break;
case 3:printf("enter the elements:-");
scanf("%d",&m);
printf("Enter the position after inserted:-");
scanf("%d",&pos);
addafter(m,pos);
20
break;
case 4:if(start==NULL)
{
printf("List is Empty:-");
continue;
}
printf("Enter the elements for deletion:-");
scanf("%d",&m);
del(m);
break;
case 5:disp();
break;
case 6:exit(0);
break;
default:printf("wrong Choice");
}
}
getch();
}
create(int data)
{
struct node *q, *temp;
temp=malloc(sizeof(struct node));
temp->info=data;
temp->link=NULL;
if(start==NULL)
start=temp;
else
{
q=start;
while(q->link!=NULL)
q=q->link;
q->link=temp;
}
}
addafter(int data,int pos)
{
struct node *q,*temp; int i;
q=start;
for(i=0;i<pos-1;i++)
{
q=q->link;
if(q==NULL)
{
printf("There are less elements:-");
return;
}
}
temp=malloc(sizeof(struct node));
temp->link=q->link;
21
temp->info=data;
q->link=temp;
}
addatbeg(int data)
{
struct node *q,*temp;
temp=malloc(sizeof(struct node));
temp->info=data;
temp->link=start;
start=temp;
}
del(int data)
{
struct node *temp, *q;
if(start->info==data)
{
temp=start;
start=start->link;
free(temp); return;
}
q=start;
while(q->link->link! =NULL)
{
if(q->link->info==data)
{
temp=q->link;
q->link=temp->link;
free(temp);
return;
}
q=q->link;
}
if(q->link->info==data)
{
temp=q->link;
free(temp);
q->link=NULL;
return;
}
}
disp()
{
struct node *q;
if(start==NULL)
{
printf("List is Empty");
return;
}
q=start;
22
printf("List is:-\n");
while(q!=NULL)
{
printf("%d->",q->info);
q=q->link;
}
printf("NULL");
}
Output:
1. Create
2. Insertatbeg
3. Insertatmiddle
4. Delete
5. Display
6. Exit
Enter the choice: -
1
how many nodes u want to insert: -3
Enter the data: -
123
1. Create
2. Insertatbeg
3. Insertatmiddle
4. Delete
5. Display
6. Exit
Enter the choice: -
2
enter the elements: -
12
1. Create
2. Insertatbeg
3. Insertatmiddle
4. Delete
5. Display
6. Exit
Enter the choice: -
5
List is: -
12->1->2->3
23
EXPERIMENT NO 3.2
OBJECTIVE
#include<stdio.h>
#include<stdio.h>
struct dllnode
{
int info;
struct dllnode *prev;
struct dll *next;
};
void create (struct dllnode *);
void insert(struct dllnode *);
void delete(struct dllnode *);
void display(struct dllnode *);
void main()
{
struct dllnode *node;
char ch=’1’;
node=(struct dllnode *)malloc(sizeof(struct dllnode));
if(node==NULL)
{
printf(“\n out of memory”);
exit(0);
}
create(node);
while(ch!=’3’)
{
printf(“\n 1. Insert at End”);
printf(“\n 2. Display”);
printf(“\n 3. Delete at Beg”);
printf(“\n 4. Exit”);
printf(“\n Enter your choice:”);
ch=getchar();
switch(ch)
{
case ‘1’:
insert(node);
break;
case ‘2’:
display(node);
break;
case ‘3’:
delete(node);
node=start;
break;
case ‘4’:
24
break;
default:
printf(“Wrong Choice”);
}
}
}
Output:
1. Create List
2. Insert at End
3. Delete at Beginning
4. Display
5. Exit
Enter your choice: 1
Enter node value: 10
Add more? (Y/N): y
Enter node value: 20
Add more? (Y/N): y
Enter node value: 30
Add more? (Y/N): n
1. Create List
2. Insert at End
3. Delete at Beginning
4. Display
5. Exit
Enter your choice: 4
26
Forward: 10 20 30
Reverse: 30 20 10
27
Overview of StackUsing Array and Linked List
Stack: -
A stack is a particular kind of abstract data type or collection in which the principal (or only) operations on the
collection are the addition of an entity to the collection, known as push and removal of an entity, known as
pop. The relation between the push and pop operations is such that the stack is a Last-In-First-Out (LIFO) data
structure. In a LIFO data structure, the last element added to the structure must be the first one to be removed.
This is equivalent to the requirement that, considered as a linear data structure, or more abstractly a sequential
collection, the push and pop operations occur only at one end of the structure, referred to as the top of the
stack. Often a peek or top operation is also implemented, returning the value of the top element without
removing it.
A stack may be implemented to have a bounded capacity. If the stack is full and does not contain enough space
to accept an entity to be pushed, the stack is then considered to be in an overflow state. 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, it goes into underflow state, which means no items are present in stack
to be removed.
A stack is a restricted data structure, because only a small number of operations are performed on it. The nature
of the pop and push operations also mean that stack elements have a natural order. Elements are removed from
the stack in the reverse order to the order of their addition. Therefore, the lower elements are those that have
been on the stack the longest.
28
EXPERIMENT NO 4 . 1
OBJECTIVE
#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 5
int stack[MAX_SIZE];
void push();
int pop();
void traverse();
int is_empty();
int top_element();
int top = -1;
main()
{
int element, choice;
while(1)
{
printf("Stack Operations.\n");
printf("1. Insert into stack (Push operation).\n");
printf("2. Delete from stack (Pop operation).\n");
printf("3. Print top element of stack.\n");
printf("4. Check if stack is empty.\n");
printf("5. Traverse stack.\n");
printf("6. Exit.\n");
printf("Enter your choice.\n");
scanf("%d",&choice);
switch (choice)
{
case 1:
if (top == MAX_SIZE - 1)
printf("Error: Overflow\n\n");
else
{
printf("Enter the value to insert.\n");
scanf("%d",&element);
push(element);
}
break;
case 2:
if (top == -1)
printf("Error: Underflow.\n\n");
else
{
element = pop();
printf("Element removed from stack is %d.\n", element);
}
29
break;
case 3:
if(!is_empty())
{
element = top_element();
printf("Element at the top of stack is %d\n\n", element);
}
else
printf("Stack is empty.\n\n");
break;
case 4:
if(is_empty())
printf("Stack is empty.\n\n");
else
printf("Stack is not empty.\n\n");
break;
case 5:
traverse();
break;
case 6:
exit(0);
}
}
}
void push(int value)
{
top++;
stack[top] = value;
}
int pop()
{
int element;
if ( top == -1 )
return top;
element = stack[top];
top--;
return element;
}
void traverse()
{
int d;
if ( top == - 1 )
{
printf("Stack is empty.\n\n");
return;
}
printf("There are %d elements in stack.\n", top+1);
for ( d = top ; d >= 0 ; d-- )
printf("%d\n", stack[d]);
30
printf("\n");
}
int is_empty()
{
if (top == - 1)
return 1;
else
return 0;
}
int top_element()
{
return stack[top];
}
Output:
Stack Operations.
1. Insert into stack (Push operation).
2. Delete from stack (Pop operation).
3. Print top element of stack.
4. Check if stack is empty.
5. Traverse stack.
6. Exit.
Enter your choice.
1
Enter the value to insert
2
Enter your choice.
1
Enter the value to insert
3
Stack Operations.
1. Insert into stack (Push operation).
2. Delete from stack (Pop operation).
3. Print top element of stack.
4. Check if stack is empty.
5. Traverse stack.
6. Exit.
Enter your choice.
5
Traverse Stack:
32
31
EXPERIMENT NO 4 . 2
OBJECTIVE
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#define MAX_SIZE 3
void push(int i);
void pop(void);
int choice, i;
int *tos, *p1, arr_stack[MAX_SIZE];
int exit_p = 1;
int main()
{
int value;
tos = arr_stack; /* tos points to the top of stack */
p1 = arr_stack; /* initialize p1 */
printf("\n Simple Stack Example - Pointers");
do {
printf("\nStack Pointer : Main Menu");
printf("\n1.Push \t2.Pop \tOthers to exit : Your Choice : ");
scanf("%d", &choice);
switch (choice)
{
case 1:
printf("Enter value: ");
scanf("%d", &value);
push(value);
break;
case 2:
pop();
break;
default:
exit_p = 0;
break;
}
} while (exit_p);
return 0;
}
void push(int i) {
if (p1 == (tos + MAX_SIZE))
{
printf("\nStatus : Stack Overflow.\n");
} else
{
*p1 = i;
printf("\nPush Value : %d ", *(p1));
p1++;
}
32
}
void pop(void)
{
if (p1 == tos)
{
printf("\nStatus : Stack Underflow.\n");
} else
{
p1--;
printf("\nPop Value : %d ", *(p1));
}
}
Output:
Stack Pointer: Main Menu
1. Push 2. Pop Others to exit: Your Choice: 1
Enter value: 100
Push Value: 100
Stack Pointer: Main Menu
1. Push 2. Pop Others to exit: Your Choice: 1
Enter value: 200
Push Value: 200
Stack Pointer: Main Menu
1. Push 2. Pop Others to exit: Your Choice: 1
Enter value: 300
Push Value: 300
Stack Pointer: Main Menu
1. Push 2. Pop Others to exit: Your Choice: 1
Enter value: 400
Status: Stack Overflow.
33
EXPERIMENT NO 4 . 3
OBJECTIVE
Write a program to convertinfix expression to its postfix form using stack operations.
#include <stdio.h>
#include <stdlib.h> /* for exit() */
#include <ctype.h> /* for isdigit(char) */
#include <string.h>
#define SIZE 100
/* Global variables */
char stack[SIZE];
int top = -1;
/* Push operation */
void push(char item)
{
if (top >= SIZE - 1)
{
printf("\nStack Overflow.");
}
else
{
top = top + 1;
stack[top] = item;
}
}
/* Pop operation */
char pop()
{
char item;
if (top < 0)
{
printf("Stack underflow: invalid infix expression");
getchar();
/* Underflow may occur for invalid expression where (and) are not matched */
exit(1);
}
else
{
item = stack[top];
top = top - 1;
return item;
}
}
/* Function to check if a symbol is an operator */
int is_operator(char symbol)
{
if (symbol == '^' || symbol == '*' || symbol == '/' || symbol == '+' || symbol == '-')
{
return 1;
}
34
else
{
return 0;
}
}
/* Function to determine the precedence of operators */
int precedence(char symbol)
{
if (symbol == '^')
{
/* Exponent operator, highest precedence */
return 3;
}
else if (symbol == '*' || symbol == '/')
{
return 2;
}
else if (symbol == '+' || symbol == '-')
{
/* Lowest precedence */
return 1;
}
else
{
return 0;
}
}
/* Convert Infix expression to Postfix */
void InfixToPostfix(char infix_exp[], char postfix_exp[])
{
int i = 0, j = 0;
char item;
char x;
push('('); /* Push '(' onto stack */
strcat(infix_exp, ")"); /* Add ')' to infix expression */
item = infix_exp[i]; /* Initialize before loop */
while (item != '\0')
{ /* Run loop till end of infix expression */
if (item == '(')
{
push(item);
}
else if (isdigit(item) || isalpha(item))
{
postfix_exp[j] = item; /* Add operand symbol to postfix expression */
j++;
}
else if (is_operator(item) == 1)
{ /* Symbol is operator */
x = pop();
while (is_operator(x) == 1 && precedence(x) >= precedence(item))
{
postfix_exp[j] = x; /* Pop all higher precedence operators */
35
j++;
x = pop(); /* Add them to postfix expression */
}
push(x); /* Push the operator back onto the stack */
push(item); /* Push the current operator symbol onto the stack */
}
else if (item == ')')
{/* If current symbol is ')' */
x = pop(); /* Pop and keep popping until '(' is encountered */
while (x != '(')
{
postfix_exp[j] = x; j++;
x = pop();
}
}
else
{ /* Invalid symbol */ printf("\nInvalid infix Expression.\n");
getchar();
exit(1);
}
i++;
item = infix_exp[i]; /* Go to next symbol of infix expression */
}
/* End of while loop */
if (top > 0)
{
printf("\nInvalid infix Expression.\n");
getchar();
exit(1);
}
postfix_exp[j] = '\0';
}
int main()
{
char infix[SIZE], postfix[SIZE]; /* Declare infix and postfix strings */
printf("ASSUMPTION: The infix expression contains single letter variables and single digit constants
only.\n");
printf("\nEnter Infix expression: ");
gets(infix); /* Get the infix expression from the user */
InfixToPostfix(infix, postfix); /* Convert to postfix */
printf("Postfix Expression: ");
puts(postfix); /* Print the postfix expression */
return 0;
}
Output:
Enter Infix expression: a+b*c
Postfix Expression: abc*+
36
EXPERIMENT 4.4
OBJECTIVE
Write a program to implement Fibonacci Series and Tower of Hanoi Using Recursion.
#include <stdio.h>
int fibonacci(int n)
{
if(n == 0)
return 0;
else if(n == 1)
return 1; else
return (fibonacci(n-1) + fibonacci(n-2));
}
int main()
{
int n;
printf("Enter the number of terms\n");
scanf("%d", &n);
printf("Fibonacci Series: ");
for (int i = 0; i < n; i++)
{
printf("%d ", fibonacci(i));
}
return 0;
}
Output:
Enter the number of terms:
5
Fibonacci Series:
0,1,1,2,3
37
int main()
{
int n = 3;
char from = 'A';
char to = 'B';
char via = 'C';
//calling hanoi() method
hanoi(n, from, via, to);
}
Output:
Move disk 1 from A to C
Move disk 2 from A to B
Move disk 1 from C to B
Move disk 3 from A to C
Move disk 1 from B to A
Move disk 2 from B to C
Move disk 1 from A to C
38
Overview of Queue Using Array and Linked List
Queue: -
A queue is a particular kind of abstract data type or collection in which the entities in the collection are kept
in order and the principal (or only) operations on the collection are the addition of entities to the rear terminal
position, known as en-queue, and removal of entities from the front terminal position, known as de-queue.
This makes the queue a First-In-First- Out (FIFO) data structure. In a FIFO data structure, the first element
added to the queue will be the first one to be removed. This is equivalent to the requirement that once a new
element is added, all elements that were added before have to be removed before the new element can be
removed. Often a peek or front operation is also entered, returning the value of the front element without de-
queuing it. A queue is an example of a linear data structure, or more abstractly a sequential collection.
Queues provide services in computer science, transport, and operations research where various entities such
as data, objects, persons, or events are stored and held to be processed later. In these contexts, the queue
performs the function of a buffer.
Queues are common in computer programs, where they are implemented as data structures coupled with
access routines, as an abstract data structure or in object-oriented languages as classes. Common
implementations are circular buffers and linked lists.
39
EXPERIMENT NO 5 . 1
OBJECTIVE
#include<stdio.h>
#include<conio.h>
#define MAX 10
void insert(int);
int del();
int queue[MAX], rear=0, front=0;
void display();
int main()
{
char ch , a='y';
int choice, token;
printf("\n1.Insert");
printf("\n2.Delete");
printf("\n3.Show or display");
do
{
printf("\nEnter your choice for the operation: ");
scanf("%d",&choice);
switch(choice)
{
case 1: insert(token);
display();
break;
case 2:
token=del();
printf("\nThe token deleted is %d",token);
display();
break;
case 3:
display();
break;
default:
printf("Wrong choice");
break;
}
printf("\nDo you want to continue(y/n):");
ch=getch();
}
while(ch=='y'||ch=='Y');
getch();
}
void display()
{
int i;
printf("\nThe queue elements are:");
40
for(i=rear;i<front;i++)
{
printf("%d ",queue[i]);
}
}
void insert(int token)
{
char a;
if(rear==MAX)
{
printf("\nQueue full");
return;
}
do
{
printf("\nEnter the token to be inserted:");
scanf("%d",&token);
queue[front]=token;
front=front+1;
printf("do you want to continue insertion Y/N");
a=getch();
}
while(a=='y');
}
int del()
{
int t; if(front==rear)
{
printf("\nQueue empty");
return 0;
}
rear=rear+1;
t=queue[rear-1];
return t;
}
Output:
1. Insert
2.Delete
3.Show or display
Enter your choice for the operation:1
Enter the token to be inserted: 2
The queue elements are: 2
41
EXPERIMENT NO 5 . 2
OBJECTIVE
#include<stdio.h>
#include<stdlib.h>
struct node
{
int data;
struct node*next;
}*head=NULL;
struct node *create(int value)
{
struct node *temp;
temp=(struct node*)malloc(sizeof(struct node));
temp->data=value;
temp->next=NULL;
return temp;
}
void enqueue(int value)
{
struct node *newnode, *temp;
newnode=create(value);
if(head==NULL)
{
head=newnode;
}
else
{
temp=head;
while(temp->next!=NULL)
{
temp=temp->next;
}
temp->next=newnode;
}
}
void dequeue()
{
struct node *temp;
if(head==NULL)
{
printf("Queue Underflow");
}
else
{
temp=head;
head=head->next;
free(temp);
42
}
}
void display()
{
struct node *temp;
if(head==NULL)
{
printf("Queue is empty");
}
else
{
temp=head;
while(temp->next!=NULL)
{
printf("%d, ",temp->data);
temp=temp->next;
}
printf("%d",temp->data);
}
}
void main()
{
int ch,pos,value;
do
{
printf("\n1. Insert\n2. Delete\n3. Display\n4. Exit");
printf("\nEnter your choice: ");
scanf("%d",&ch);
switch(ch)
{
case 1: printf("Enter data to insert: ");
scanf("%d",&value);
enqueue(value);
break;
case 2: dequeue();
break;
case 3: display();
break;
case 4:break;
default: printf("\nyour choice is wrong!..");
}
}while(ch!=4);
}
Output:
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 1
Enter data to insert: 10
1. Insert
43
2. Delete
3. Display
4. Exit
Enter your choice: 1
Enter data to insert: 20
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 1
Enter data to insert: 30
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 3
10, 20, 30
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 2
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 3
20, 30
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 2
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 3
30
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 2
1. Insert
2. Delete
3. Display
4. Exit
Enter your choice: 2
Queue Underflow
44
EXPERIMENT NO 5 . 3
OBJECTIVE
#include<stdio.h>
#include<stdlib.h>
#define SIZE 100
int queue[SIZE];
int f = -1;
int r = -1;
void insert_r(int x)
{
if(f == (r+1)%SIZE)
{
printf("\nQueue Overflow");
}
else if(r == -1)
{
f = 0;
r = 0;
queue[r] = x;
}
else
{
r = (r+1) %SIZE;
queue[r] = x;
}
}
void insert_f(int x)
{
if(f == (r+1)%SIZE)
{
printf("\nQueue Overflow");
}
else if(r == -1)
{
f = 0;
r = 0;
queue[r] = x;
}
else
{
f = (f+SIZE-1) %SIZE;
queue[f] = x;
}
}
int delete_r()
{
int x;
if(f == -1)
45
{
printf("\nQueue Underflow");
}
else if(f == r)
{
x = queue[f];
f = -1;
r = -1;
}
else
{
x = queue[r];
r = (r+SIZE-1)%SIZE;
}
return x;
}
int delete_f()
{
int x;
if(f == -1)
{
printf("\nQueue Underflow");
}
else if(f == r)
{
x = queue[f];
f = -1;
r = -1;
}
else
{
x = queue[f];
f = (f+1)%SIZE;
}
return x;
}
void main()
{
int ch,x;
while(1)
{
printf("\n");
printf("1: Insert From Front\n");
printf("2: Insert From Rear\n");
printf("3: Delete From Front\n");
printf("4: Delete From Rear\n");
printf("5: Exit Program\n");
printf("Enter Your Choice:");
scanf("%d",&ch);
switch(ch)
{
case 1:
printf("\nEnter Integer Data :");
46
scanf("%d",&x);
insert_f(x);
break;
case 2:
printf("\nEnter Integer Data :");
scanf("%d",&x);
insert_r(x);
break;
case 3:
printf("\nDeleted Data From Front End: %d",delete_f());
break;
case 4:
printf("\nDeleted Data From Back End: %d",delete_r());
break;
case 5:
exit(0);
break;
}
}
}
Output:
1: Insert From Front
2: Insert From Rear
3: Delete From Front
4: Delete From Rear
5: Exit Program
Enter Your Choice: 2
Enter Integer Data: 10
1: Insert From Front
2: Insert From Rear
3: Delete From Front
4: Delete From Rear
5: Exit Program
Enter Your Choice: 2
Enter Integer Data: 20
1: Insert From Front
2: Insert From Rear
3: Delete From Front
4: Delete From Rear
5: Exit Program
Enter Your Choice: 1
Enter Integer Data: 5
1: Insert From Front
2: Insert From Rear
3: Delete From Front
4: Delete From Rear
5: Exit Program
47
Enter Your Choice: 3
Deleted Data From Front End: 5
1: Insert From Front
2: Insert From Rear
3: Delete From Front
4: Delete From Rear
5: Exit Program
Enter Your Choice: 4
Deleted Data From Back End: 20
1: Insert From Front
2: Insert From Rear
3: Delete From Front
4: Delete From Rear
5: Exit Program
Enter Your Choice: 5
48
EXPERIMENT NO 5 . 4
OBJECTIVE
51
elements are:
20
30
1: insert
2: deletion
3: display
4: exit
Enter choice:1
enter the no:
40
40 succ. inserted
1: insert
2: deletion
3: display
4: exit
Enter choice:1
enter the no:
50
50 succ. inserted
1: insert
2: deletion
3: display
4: exit
Enter choice:1
enter the no:
60
Queue is overflow
1: insert
2: deletion
3: display
4: exit
Enter choice:3
elements are:
20
30
40
50
1: insert
2: deletion
3: display
4: exit
Enter choice:4
program ends
52
Overview of Tree
Tree: -
A tree is a widely used abstract data type (ADT) or data structure implementing this ADT that simulates a
hierarchical tree structure, with a root value and sub-trees of children, represented as a set of linked nodes.
A tree data structure can be defined recursively (locally) as a collection of nodes (starting at a root node),
where each node is a data structure consisting of a value, together with a list of references to nodes (the
"children"), with the constraints that no reference is duplicated, and none points to the root.
Alternatively, a tree can be defined abstractly as a whole (globally) as an ordered tree, with a value assigned
to each node. Both these perspectives are useful: while a tree can be analyzed mathematically as a whole, when
actually represented as a data structure it is usually represented and worked with separately by node (rather
than as a list of nodes and an adjacency list of edges between nodes, as one may represent a digraph, for
instance). For example, looking at a tree as a whole, one can talk about "the parent node" of a given node, but
in general as a data structure a given node only contains the list of its children, but does not contain a reference
to its parent
There are three types of depth-first traversal: pre-order, in-order, and post-order. For a binary tree, they are
defined as operations recursively at each node, starting with the root node as follows:
Pre-order
Visit the root.
Traverse the left subtree.
Traverse the right subtree.
In-order (symmetric)
Traverse the left subtree.
Visit the root.
Traverse the right subtree.
Post-order
Traverse the left subtree.
Traverse the right subtree.
Visit the root.
The trace of a traversal is called a sequentialization of the tree. No one sequentialization according to pre-, in-
or post-order describes the underlying tree uniquely. Given a tree with distinct elements, either pre-order or
post-order paired with in-order is sufficient to describe the tree uniquely. However, pre-order with post- order
leaves some ambiguity in the tree structure.
53
EXPERIMENT NO 6.1
OBJECTIVE
54
case 5:
exit();
default :
printf(" Wrong Choice ");
}// switch close
}// while close
getch();
} //main close
56
} return (0);
} //fun close
preorder(struct tree *ptr)
{
if (ptr!=NULL)
{
printf("%d",ptr->head);
preorder(ptr->l);
preorder(ptr->r);
} // if close
return (0);
} //fun close
postorder(struct tree *ptr)
{
if (ptr!=NULL)
{
postorder(ptr->l);
postorder(ptr->r);
printf("%d",ptr->head);
} // if close
return(0);
} //fun close
Output:
Post order traversal
60 70 40 50 20 30 10
57
Overview of AVL Tree
An AVL tree defined as a self-balancing Binary Search Tree (BST) where the difference between
heights of left and right subtrees for any node cannot be more than one. The difference between the
heights of the left subtree and the right subtree for any node is known as the balance factor of the node.
AVL trees are often compared to red-black trees, which support similar operations and take similar time
for basic operations. However, AVL trees are faster than red-black trees for lookup-intensive
applications because they are more strictly balanced.
Balancing factor
The difference between the heights of a node's left and right subtrees is called the balancing factor.
For a node to be balanced, the balancing factor must be -1, 0, or 1.
Rebalancing
If the heights of a node's subtrees differ by more than one, the tree is rebalanced to restore balance.
This is done by performing one or more tree rotations.
Rotation types
There are four types of rotations that can be performed to balance an AVL tree: LL, RR, LR, and RL.
Each rotation type requires different node repositioning.
58
EXPERIMENT NO 7.1
OBJECTIVE
int key;
struct Node* left;
struct Node* right;
int height;
};
// Function to get height of the node
int getHeight(struct Node* n)
{
if (n == NULL)
return 0;
return n->height;
}
// Function to create a new node
struct Node* createNode(int key)
{
struct Node* node= (struct Node*) malloc(sizeof(struct Node));
node->key = key;
node->left = NULL;
node->right = NULL;
node->height = 1; // New node is initially added at leaf
return node;
}
// Utility function to get the maximum of two integers
int max(int a, int b)
{
return (a > b) ? a : b;
}
// Function to get balance factor of a node
int getBalanceFactor(struct Node* n)
{
if (n == NULL)
return 0;
return getHeight(n->left) - getHeight(n->right);
}
// Right rotation function
struct Node* rightRotate(struct Node* y)
{
struct Node* x = y->left;
struct Node* T2 = x->right;
// Perform rotation
x->right = y;
59
y->left = T2;
60
// Update heights
y->height = max(getHeight(y->left), getHeight(y->right)) + 1;
x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
return x;
}
// Left rotation function
struct Node* leftRotate(struct Node* x)
{
struct Node* y = x->right;
struct Node* T2 = y->left;
// Perform rotation
y->left = x;
x->right = T2;
// Update heights
x->height = max(getHeight(x->left), getHeight(x->right)) + 1;
y->height= max(getHeight(y->left), getHeight(y->right)) + 1;
return y;
}
// Function to insert a key into AVL tree
struct Node* insert(struct Node* node, int key)
{
// 1. Perform standard BST insertion
if (node == NULL)
return createNode(key);
if (key < node->key)
node->left = insert(node->left, key);
else if (key > node->key)
node->right = insert(node->right, key);
else // Equal keys are not allowed in BST
return node;
// 2. Update height of this ancestor node
node->height = 1+ max(getHeight(node->left), getHeight(node->right));
// 3. Get the balance factor of this ancestor node to // check whether this node became unbalanced
int balance = getBalanceFactor(node);
// 4. If the node becomes unbalanced, then there are 4
// cases
// Left Left Case
if (balance > 1 && key < node->left->key)
return rightRotate(node);
// Right Right Case
if (balance < -1 && key > node->right->key)
return leftRotate(node);
// Left Right Case
if (balance > 1 && key > node->left->key)
{
node->left = leftRotate(node->left);
return rightRotate(node);
}
// Right Left Case
if (balance < -1 && key < node->right->key)
{
node->right = rightRotate(node->right);
return leftRotate(node);
61
}
// Return the (unchanged) node
pointer return node;
}
// Function to perform preorder traversal of AVL
tree void inOrder(struct Node* root)
{
if (root != NULL)
{
inOrder(root->left);
printf("%d ", root-
>key); inOrder(root-
>right);
}
}
// Main
function int
main()
{
struct Node* root = NULL;
// Inserting
nodes root =
insert(root, 1);
root =
insert(root, 2);
root =
insert(root, 4);
root =
insert(root, 5);
root =
insert(root, 6);
root =
insert(root, 3);
// Print preorder traversal of the AVL
tree printf("Inorder traversal of AVL
tree: "); inorder(root);
return 0;
}
Output:
Inorder traversal of AVL tree: 1 2 3 4 5 6
62
Overview of Linear Search and Binary Search and Hashing
Linear Search:
Linear Search is a simple searching technique that checks each element in the list sequentially
until the desired element is found or the end is reached.
Start from the first element.
Compare each element with the target.
If a match is found, return the index.
If the end is reached without a match, return -1 (not found).
Binary Search:
Binary Search is an efficient algorithm that finds an element in a sorted array by repeatedly dividing the
search interval in half.
Check the middle element.
If it's equal to the target, return index.
If the target is less than the middle, search the left half.
If the target is greater, search the right half.
Repeat until found or search space is empty.
Hashing:
Hashing is a technique used in data structures to map data (keys) to a fixed-size address (index) in
memory — typically for fast retrieval using a hash function.
In simple terms:
Hashing converts a key (e.g., a name, ID, or string) into an index in an array (called a hash
table), enabling quick search, insertion, and deletion.
63
EXPERIMENT NO 8 .1
OBJECTIVE
Write a Program to implement Linear Search using array.
#include<stdio.h>
void main()
{
int a[5],i,flag=0,m;
printf("Enter the number of Array\n");
for(i=0;i<5;i++)
{
scanf("%d",&a[i]);
}
printf("The Array Elements Is: -\n");
for(i=0;i<5;i++)
{
printf("%d\t",a[i]);
}
printf("\n Enter the number to be search: ");
scanf("%d",&m);
for(i=0;i<5;i++)
{
if(a[i]==m)
{
flag=1;
break;
}
}
if(flag==1)
printf("Element Found at position %d ",i);
else
printf("Element Not Found");
}
Output:
Enter the number of Array
5
12
3
4
2
The Array Elements Is: -
5 12 3 4 2
Enter the number to be search: 12
Element Found at Position: 1
64
EXPERIMENT NO 8 . 2
OBJECTIVE
#include<stdio.h>
void main()
{
int a[10],i,n,m,c=0,l,u,mid;
printf("Enter the size of an array: ");
scanf("%d",&n);
printf("Enter the elements in ascending order: ");
for(i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
printf("Enter the number to be search: ");
scanf("%d",&m);
l=0,u=n-1;
while(l<=u)
{
mid=(l+u)/2;
if(m==a[mid])
{
c=1;
break;
}
else if(m<a[mid])
{
u=mid-1;
}
else
l=mid+1;
}
if(c==0)
printf("The number is not found.");
else
printf("The number is found.");
}
Output:
Enter the size of an array: 6
Enter the elements in ascending order: 1
2
3
4
5
6
Enter the number to be search: 5
The number is found.
65
EXPERIMENT NO 8 . 3
OBJECTIVE
#include <stdio.h>
#include <stdlib.h>
#define SIZE 10
int hashTable[SIZE];
void init() {
for (int i = 0; i < SIZE; i++)
{
hashTable[i] = -1;
}
}
int hash(int key)
{
return key % SIZE;
}
void insert(int key)
{
int index = hash(key);
int originalIndex = index;
int i = 0;
while (hashTable[index] != -1 && i < SIZE)
{
index = (originalIndex + ++i) % SIZE;
}
if (i < SIZE)
{
hashTable[index] = key;
printf("Inserted %d at index %d\n", key, index);
} else
{
printf("Hash table is full. Cannot insert %d\n", key);
}
}
void search(int key)
{
int index = hash(key);
int originalIndex = index;
int i = 0;
while (hashTable[index] != -1 && i < SIZE)
{
if (hashTable[index] == key)
{
printf("Found %d at index %d\n", key, index);
return;
}
index = (originalIndex + ++i) % SIZE;
}
66
printf("%d not found in hash table.\n", key);
}
void display()
{
printf("\nHash Table:\n");
for (int i = 0; i < SIZE; i++) {
printf("Index %d: %d\n", i, hashTable[i]);
}
}
int main()
{
int choice, key;
init();
while (1)
{
printf("\nMenu:\n");
printf("1. Insert\n2. Search\n3. Display\n4. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
printf("Enter key to insert: ");
scanf("%d", &key);
insert(key);
break;
case 2:
printf("Enter key to search: ");
scanf("%d", &key);
search(key);
break;
case 3:
display();
break;
case 4:
exit(0);
default:
printf("Invalid choice\n");
}
}
return 0;
}
Output:
Menu:
1. Insert
2. Search
3. Display
4. Exit
Enter your choice: 1
Enter key to insert: 15
Inserted 15 at index 5
Menu:
1. Insert
67
2. Search
3. Display
4. Exit
Enter your choice: 1
Enter key to insert: 25
Inserted 25 at index 6
Menu:
1. Insert
2. Search
3. Display
4. Exit
Enter your choice: 1
Enter key to insert: 35
Inserted 35 at index 7
Menu:
1. Insert
2. Search
3. Display
4. Exit
Enter your choice: 3
Hash Table:
Index 0: -1
Index 1: -1
Index 2: -1
Index 3: -1
Index 4: -1
Index 5: 15
Index 6: 25
Index 7: 35
Index 8: -1
Index 9: -1
Menu:
1. Insert
2. Search
3. Display
4. Exit
Enter your choice: 2
Enter key to search: 25
Found 25 at index 6
68
Overview of Graph
Graph:
BFS: -
In graph theory, breadth-first search (BFS) is a strategy for searching in a graph when search is limited to
essentially two operations: (a) visit and inspect a node of a graph; (b) gain access to visit the nodes that
neighbor the currently visited node. The BFS begins at a root node and inspects all the neighboring nodes.
Then for each of those neighbor nodes in turn, it inspects their neighbor nodes which were unvisited, and
so on. Compare BFS with the equivalent, but more memory-efficient Iterative deepening depth-first search
and contrast with depth-first search.
DFS: -
Depth-first search (DFS) is an algorithm for traversing or searching tree or graph data structures. One
starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as
possible along each branch before backtracking.
69
EXPERIMENT NO 9.1
OBJECTIVE
char node[10];
struct tree *left,*right;
} *temp, *root=NULL,*t,*q[25];
int d,a[10],jj,ii,ti,b,fi,ri;
char ch[10];
void main()
{
clrscr();
input();
output();
getch();
}
void input()
{
int n,m,r,i,f;
printf("Enter the no of depth:-");
scanf("%d",&d);
n=pow(2,d+1)-1;
for(i=1;i<=n;i++)
{
printf("Enter the %d node name:-",i);
scanf("%s",ch);
temp=(struct tree *)malloc(sizeof(struct tree));
strcpy(temp->node,ch);
temp->left=NULL;
temp->right=NULL;
if(root==NULL)
{
root=temp;
}
else
{
70
t=root; r=db(i);
71
for(f=1;f<r;f++)
{
if(a[f]==0)
{
t=t->left;
}
else
{
t=t->right;
}
}
if(a[r]==0)
{
t->left=temp;
}
else
{
t->right=temp;
}
}
}
}
void output()
{
t=root;
printf("\n Enter the name Goal:-");
scanf("%s",ch);
BFS(t);
}
int db(int n)
{
int ji=0;
while(n!=0)
{
a[ji++]=n%2;
n=n/2;
}
for(ii=0,b=ji-1;ii<b;ii++,b--)
{
ti=a[ii];
a[ii]=a[b];
a[b]=ti;
}
ji--; return
ji;
}
void BFS(struct tree *t)
72
{
int yes=0,index; fi=0;
ri=1; q[fi]=t;
printf("\n Breadth First search:-\n");
while(fi<ri)
{
t=q[fi++]; printf("%s",t->node);
if(strcmp(t->node,ch)==0)
{
yes=1;
index=fi;
}
if(t->left!=NULL)
{
q[ri++]=t->left;
}
if(t->right!=NULL)
{
q[ri++]=t->right;
}
}
if(yes==1)
printf("\n Goal State Are Present at Node %d", index);
else
printf("\n Goal State Are Not Present");
}
Output:
Input the number of vertices: 5
Input the number of edges: 6
Input edge 1 (start end): 0 1
Input edge 2 (start end): 1 2
Input edge 3 (start end): 2 3
Input edge 4 (start end): 3 4
Input edge 5 (start end): 4 0
Input edge 6 (start end): 2 4
Input the starting vertex for BFS traversal: 0
BFS Traversal Order: 0 1 4 2 3
73
EXPERIMENT NO 9.2
OBJECTIVE
char node[10];
struct tree *left,*right;
} *temp, *root=NULL, *t,*s[25];
int d,a[10],jj,ii,ti,b,top;
char ch[10];
void main()
{
clrscr();
input();
output();
getch();
}
void input()
{
int n,m,r,i,f;
printf("Enter the no of depth:-");
scanf("%d",&d);
n=pow(2,d+1)-1;
for(i=1;i<=n;i++)
{
printf("Enter the %d node name:-",i);
scanf("%s",ch);
temp=(struct tree *)malloc(sizeof(struct tree));
strcpy(temp->node,ch);
temp->left=NULL;
temp->right=NULL;
if(root==NULL)
{
root=temp;
}
else
{
74
t=root;
r=db(i);
for(f=1;f<r;f++)
{
if(a[f]==0)
{
t=t->left;
}
else
{
t=t->right;
}
}
if(a[r]==0)
{
t->left=temp;
}
else
{
t->right=temp;
}
}
}
}
void output()
{
t=root;
printf("\n Enter the name Goal:-");
scanf("%s",ch);
DFS(t);
}
int db(int n)
{
int ji=0;
while(n!=0)
{
a[ji++]=n%2;
n=n/2;
}
for(ii=0,b=ji-1;ii<b;ii++,b--)
{
ti=a[ii];
a[ii]=a[b];
a[b]=ti;
}
ji--;
return
ji;
75
}
void DFS(struct tree *t)
{
int yes=0,top=1;
s[top]=t;
printf("\n Depth First search:-\n");
while(top>0)
{
t=s[top];
top--;
printf("%s",t->node);
if(strcmp(t->node,ch)==0)
{
yes=1;
}
if(t->left!=NULL)
{
s[++top]=t->left;
}
if(t->right!=NULL)
{
s[++top]=t->right;
}
}
if(yes==1)
printf("\n Goal State Are Present");
else
printf("\n Goal State Are Not Present");
}
Output:
DFS from source: 1
12034
76