Data Structures

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 26

Industrial Training Report

Eight Week Industrial Training (MCA-211) Report on Data Structures &


Algorithms
(August 2022- September 2022)

Submitted by

Ajay Kumar, MCA-II Year (III Sem)


221029020011(21MC23)
Department of Computer Science and Engineering
Mahatma Jyotiba Phule Rohilkhand University
Bareilly A State University, Government of Uttar Pradesh, India

2021 - 2023

Page. 1
CERTIFICATE OF TRAINING

Page. 2
ACKNOWLEGDEMENT

We extend our Thanks of Internshala Trainings who has given me opportunity.

Today I am feeling a great sense of Excitement on my way to successfully complete my training


on “ Data Structure and Algorithms” under the guidance of “Mr Anand Mahajan”.

I sincerely thank him for responding great confidence and faith in my work and being with me
to encourage and guide me to successful training completion.

I should also like to thank Mr. Sarvesh Agarwal, Founder & CEO, Inernshala for their support
who have created an atmosphere to encourage me from time to time making our work easy.

Thank You…..

Student Name: Ajay kumar

Roll No: 221029020011 (21MC23)

Signature:

Page. 3
TABLE OF CONTENT

➢ Introduction to Data Structures

➢ Introduction to Algorithms

➢ Single & Double Dimensional Arrays

➢ Searching & Sorting

➢ Stacks & Queues

➢ Revision of relevant topics in C

➢ Implementation programs of Stacks & Queues

➢ Linear linked list

➢ Circular linked list

➢ Doubly linked list

➢ Trees

➢ Graphs
➢ References…

Page. 4
Introduction to Data Structure

Data Structure is a way of collecting and organising data in such a way that we can perform
operations on these data in an effective way. Data Structures is about rendering data elements
in terms of some relationship, for better organization and storage.

Data structures are an essential concept in computer science and programming. Here are
some reasons why they are important:
1. Efficient data processing: Data structures provide a way to organize and store data
in a way that allows for efficient retrieval, manipulation, and storage of data. For
example, using a hash table to store data can provide constant-time access to data.
2. Memory management: Proper use of data structures can help to reduce memory
usage and optimize the use of resources. For example, using dynamic arrays can
allow for more efficient use of memory than using static arrays.
3. Code reusability: Data structures can be used as building blocks in various
algorithms and programs, making it easier to reuse code.
4. Abstraction: Data structures provide a level of abstraction that allows programmers
to focus on the logical structure of the data and the operations that can be
performed on it, rather than on the details of how the data is stored and
manipulated.
5. Algorithm design: Many algorithms rely on specific data structures to operate
efficiently. Understanding data structures is crucial for designing and implementing
efficient algorithms.
Overall, data structures are essential for managing and manipulating data in an efficient and
effective way. They are a fundamental concept in computer science and are used extensively
in programming and software development.
The structure of the data and the synthesis of the algorithm are relative to each other. Data
presentation must be easy to understand so the developer, as well as the user, can make an
efficient implementation of the operation.
Data structures provide an easy way of organizing, retrieving, managing, and storing data.
Here is a list of the needs for data.
• Efficient data access and manipulation: Data structures enable quick access and
manipulation of data. For example, an array allows constant-time access to
elements using their index, while a hash table allows fast access to elements based
on their key. Without data structures, programs would have to search through data
sequentially, leading to slow performance.

Page. 5
• Memory management: Data structures allow efficient use of memory by allocating
and deallocating memory dynamically. For example, a linked list can dynamically
allocate memory for each element as needed, rather than allocating a fixed amount
of memory upfront. This helps avoid memory wastage and enables efficient
memory management.
• Code reusability: Data structures can be reused across different programs and
projects. For example, a generic stack data structure can be used in multiple
programs that require LIFO (Last-In-First-Out) functionality, without having to
rewrite the same code each time.
• Optimization of algorithms: Data structures help optimize algorithms by enabling
efficient data access and manipulation. For example, a binary search tree allows fast
searching and insertion of elements, making it ideal for implementing searching and
sorting algorithms.
• Scalability: Data structures enable programs to handle large amounts of data
effectively. For example, a hash table can store large amounts of data while
providing fast access to elements based on their key.
Classification/Types of Data Structures:
Data structures can be classified into two main types: primitive data structures and non-
primitive data structures.
Primitive data structures: These are the most basic data structures and are usually built into
programming languages. Examples include:
Integer
Float
Character
Boolean
Double
Void
Non-primitive data structures: These are complex data structures that are built using
primitive data types. Non-primitive data structures can be further categorized into the
following types:
Arrays: A collection of elements of the same data type, stored in contiguous memory
locations.
Linked lists: A collection of elements that are connected by links or pointers.
Stacks: A collection of elements that follow the Last-In-First-Out (LIFO) principle.
Queues: A collection of elements that follow the First-In-First-Out (FIFO) principle.
Trees: A hierarchical data structure consisting of nodes connected by edges.
Graphs: A non-linear data structure consisting of nodes and edges.

1. Linear Data Structure


Page. 6
2. Non-Linear Data Structure.
Linear Data Structure:
• A linear data structure is a type of data structure in which data elements are
arranged in a sequential order, and each element has a unique predecessor and
successor, except for the first and last elements. Linear data structures are one-
dimensional and can be traversed sequentially from the first to the last element.
• Elements are arranged in one dimension ,also known as linear dimension.
• Example: lists, stack, queue, etc.
Non-Linear Data Structure:
• A Non-linear data structure is a type of data structure in which data elements are
not arranged in a sequential order, and each element may have one or more
predecessors and successors. Non-linear data structures can represent complex
relationships between data elements, such as hierarchies, networks, and graphs.
• Elements are arranged in one-many, many-one and many-many dimensions.
• Example: tree, graph, table, etc.

Introduction to Algorithms

An algorithm is a finite set of instructions or logic, written in order, to accomplish a certain


predefined task. Algorithm is not the complete code or program, it is just the core
logic(solution) of a problem, which can be expressed either as an informal high level
description as pseudocode or using a flowchart.
Every Algorithm must satisfy the following properties:
Input- There should be 0 or more inputs supplied externally to the algorithm.
Output- There should be atleast 1 output obtained.
Definiteness- Every step of the algorithm should be clear and well defined.
Finiteness- The algorithm should have finite number of steps.
Correctness- Every step of the algorithm must generate a correct output.
Page. 7
An algorithm is said to be efficient and fast, if it takes less time to execute and consumes less
memory space. The performance of an algorithm is measured on the basis of following
properties :
Time Complexity
Space Complexity

Space Complexity:
Its the amount of memory space required by the algorithm, during the course of its execution.
Space complexity must be taken seriously for multi-user systems and in situations where
limited memory is available.
An algorithm generally requires space for following components :
Instruction Space: Its the space required to store the executable version of the program. This
space is fixed, but varies depending upon the number of lines of code in the program.
Data Space: Its the space required to store all the constants and variables(including temporary
variables) value.
Environment Space: Its the space required to store the environment information needed to
resume the suspended function.
To learn about Space Complexity in detail, jump to the Space Complexity tutorial.

Time Complexity:
Time Complexity is a way to represent the amount of time required by the program to run till
its completion. It's generally a good practice to try to keep the time required minimum, so that
our algorithm completes it's execution in the minimum time possible. We will study
about Time Complexity in details in later sections.

Single & Double Dimensional Arrays

An array is a collection of similar data types (like int, float, or char), which takes memory in a
contiguous fashion in Primary memory locations.
We can declare an array in C as
int arr[50];
Where arr is an array with can hold 50 elements of integer types.
Two Type of array:
1). Single/One Dimensional array
2). Double-Dimensional Array

One Dimensional Array


Declaration of one dimensional array:
An array can be declared with the bracket punctuators [ ], as shown in the below syntax:

Page. 8
Data_Type Array_Name[Number_Of_Elements]

The below example shows a declaration of an array having the capacity to hold 50 elements of
type integers and the name of that array is arr :
int arr[50];
Initializing the array:
We can initialize an array in C by assigning value to each index one by one or by using a single
statement as follows −
Example 1 :
Assign one value each time to the array
int arr[50];
arr[0]=12;
arr[1]= 43;
arr[2] = 14;
.
.
arr[49] = 54;
Example 2:
Using a single statement
int arr[5] = {10,32,11,45,38};

Program in C to implement One dimensional array:


#include<stdio.h>
int main () {
int n[50]; /* n is an array of 50 integers */
int i,j;
/* initialize elements of array n to 0 */
for ( i = 0; i <= 50; i++ ) {
n[ i ] = i + 50; /* set element at location i to i + 50 */
}
/* output each array element's value */
for (j = 0; j<= 50; j++ ) {
printf("Element[%d] = %d\n", j, n[j] );
}
return 0;
}
Two Dimensional Array in C
The two-dimensional array can be defined as an array of arrays. The 2D array is organized as
matrices which can be represented as the collection of rows and columns. However, 2D arrays
are created to implement a relational database lookalike data structure. It provides ease of

Page. 9
holding the bulk of data at once which can be passed to any number of functions wherever
required.

Declaration of two dimensional Array in C


The syntax to declare the 2D array is given below.
data_type array_name[rows][columns];
Consider the following example.
int twodimen[4][3];
Here, 4 is the number of rows, and 3 is the number of columns.

Initialization of 2D Array in C
In the 1D array, we don't need to specify the size of the array if the declaration and
initialization are being done simultaneously. However, this will not work with 2D arrays. We will
have to define at least the second dimension of the array. The two-dimensional array can be
declared and defined in the following way.
int arr[4][3]={{1,2,3},{2,3,4},{3,4,5},{4,5,6}};

Searching & Sorting


Searching Algorithms are designed to check for an element or retrieve an element from any data
structure where it is stored.

Based on the type of search operation, these algorithms are generally classified into two
categories:
Sequential Search: In this, the list or array is traversed sequentially and every element is
checked. For example: Linear Search.
Linear Search to find the element “20” in a given list of numbers

Interval Search: These algorithms are specifically designed for searching in sorted data-
structures. These type of searching algorithms are much more efficient than Linear Search as
they repeatedly target the center of the search structure and divide the search space in half.
For Example: Binary Search.
Binary Search to find the element “23” in a given list of numbers

Page. 10
A Sorting Algorithm is used to rearrange a given array or list of elements according to a
comparison operator on the elements. The comparison operator is used to decide the new
order of elements in the respective data structure.
For Example: The below list of characters is sorted in increasing order of their ASCII values. That
is, the character with a lesser ASCII value will be placed first than the character with a higher
ASCII value.

Some of the most common sorting algorithms are:


Selection sort.
Bubble sort.
Insertion sort.
Merge sort.
Quick sort.
Heap sort.
Counting sort.
Radix sort.

Stacks & Queues


Stack:

Page. 11
Stack is a linear data structure that follows a particular order in which the operations are
performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that
the element that is inserted last, comes out first and FILO implies that the element that is
inserted first, comes out last.

Queue :
A Queue is defined as a linear data structure that is open at both ends and the operations are
performed in First In First Out (FIFO) order.
We define a queue to be a list in which all additions to the list are made at one end, and all
deletions from the list are made at the other end. The element which is first pushed into the
order, the operation is first performed on that.

FIFO Principle of Queue:


A Queue is like a line waiting to purchase tickets, where the first person in line is the first
person served. (i.e. First come first serve).
Position of the entry in a queue ready to be served, that is, the first entry that will be removed
from the queue, is called the front of the queue(sometimes, head of the queue), similarly, the
position of the last entry in the queue, that is, the one most recently added, is called
the rear (or the tail) of the queue. See the below figure.

Page. 12
Revision of relevant topics in C
C pointer :
Pointers in C are used to store the address of variables or a memory location. This variable can be of
any data type i.e, int, char, function, array, or any other pointer. The pointer of type void is
called Void pointer or Generic pointer. Void pointer can hold address of any type of variable. The
size of the pointer depends on the computer architecture like 16-bit, 32-bit, and 64-bit.

Syntax:
datatype *var_name;
Let pointer “ptr” holds the address of an integer variable or holds the address of memory
whose value(s) can be accessed as integer values through “ptr”. So to define “ptr” we can do
it in four ways, which are as following:
int *ptr;
int* ptr;
int * ptr;
int*ptr;

Void Pointers
A Void Pointer in C can be defined as an address of any variable. It has no standard data type.
A void pointer is created by using the keyword void.

NULL Pointers
Null pointers can be created by assigning a zero value during pointer declaration. This
method is useful when no address is assigned to the pointer

Wild Pointers

Page. 13
Wild Pointers are pointers that have not been initialized with something yet. These types of
C-pointers can cause problems in our programs and can eventually cause them to crash.
While working with Wild Pointers Programmer must be very careful.

C – Functions :
Functions are sets of statements that take inputs, perform some operations, and produce
results. The operation of a function occurs only when it is called. Rather than writing the
same code for different inputs repeatedly, we can call the function instead of writing the
same code over and over again. Functions accept parameters, which are data. A function
performs a certain action, and it is important for reusing code. Within a function, there are a
number of programming statements enclosed by {}.
Example:
int sum(int a, int b);

Structures in C :
A structure is a keyword that creates user-defined data types in C/C++. A structure creates a
data type that can be used to group items of possibly different types into a single type.
Page. 14
How to create a structure?
‘struct’ keyword is used to create a structure. Following is an example.
struct address
{
char name[50];
char street[100];
char city[50];
char state[20];
int pin;
};

Implementation programs of Stacks

C program to implement stacks using arrays


#include<stdio.h>
int stack[10],choice,n,top,x,i; // Declaration of variables

void push();
void pop();
void display();

int main()
{
top = -1; // Initially there is no element in stack
printf("\n Enter the size of STACK : ");
scanf("%d",&n);
printf("\nSTACK IMPLEMENTATION USING ARRAYS\n");
do
{
printf("\n1.PUSH\n2.POP\n3.DISPLAY\n4.EXIT\n");
Page. 15
printf("\nEnter the choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
push();
break;
}
case 2:
{
pop();
break;
}
case 3:
{
display();
break;
}
case 4:
{
break;
}
default:
{
printf ("\nInvalid Choice\n");
}}}
while(choice!=4);
return 0;
}

void push()
{
if(top >= n - 1)
{
printf("\nSTACK OVERFLOW\n");

}
else
{
printf("Enter a value to be pushed : ");
Page. 16
scanf("%d",&x);
top++; // TOP is incremented after an element is pushed
stack[top] = x; // The pushed element is made as TOP
}}

void pop()
{
if(top <= -1)
{
printf("\nSTACK UNDERFLOW\n");
}
else
{
printf("\nThe popped element is %d",stack[top]);
top--; // Decrement TOP after a pop
}}

void display()
{
if(top >= 0)
{
// Print the stack
printf("\nELEMENTS IN THE STACK\n\n");
for(i = top ; i >= 0 ; i--)
printf("%d\t",stack[i]);
}
else
{
printf("\nEMPTY STACK\n");
}}
OUTPUT
Stack underflow when we try to pop an element from an empty stack

Page. 17
linked list
A linked list is a linear data structure that stores a collection of data elements dynamically.
Nodes represent those data elements, and links or pointers connect each node.
Each node consists of two fields, the information stored in a linked list and a pointer that stores
the address of its next node.
The last node contains null in its second field because it will point to no node.
A linked list can grow and shrink its size, as per the requirement.
It does not waste memory space.
Representation of a Linked List
This representation of a linked list depicts that each node consists of two fields. The first field
consists of data, and the second field consists of pointers that point to another node.

Here, the start pointer stores the address of the first node, and at the end, there is a null
pointer that states the end of the Linked List.
Creation of Node and Declaration of Linked Lists

struct node
{
int data;
struct node * next;
};
struct node * n;
n=(struct node*)malloc(sizeof(struct node*));

The linked list mainly has three types, they are:


Singly Linked List
Doubly Linked List
Circular Linked List

Singly Linked List


A singly linked list is the most common type of linked list. Each node has data and an address
field that contains a reference to the next node.

Page. 18
Doubly Linked List
There are two pointer storage blocks in the doubly linked list. The first pointer block in each
node stores the address of the previous node. Hence, in the doubly linked inventory, there are
three fields that are the previous pointers, that contain a reference to the previous node. Then
there is the data, and last you have the next pointer, which points to the next node. Thus, you
can go in both directions (backward and forward).

Circular Linked List


The circular linked list is extremely similar to the singly linked list. The only difference is that
the last node is connected with the first node, forming a circular loop in the circular linked list.

Page. 19
Circular link lists can either be singly or doubly-linked lists.
The next node's next pointer will point to the first node to form a singly linked list.
The previous pointer of the first node keeps the address of the last node to form a doubly-
linked list.
Trees

The tree is a nonlinear hierarchical data structure and comprises a collection of entities known
as nodes. It connects each node in the tree data structure using "edges”, both directed and
undirected.
The image below represents the tree data structure. The blue-colored circles depict the nodes
of the tree and the black lines connecting each node with another are called edges.
You will understand the parts of trees better, in the terminologies section.

After learning the introduction to a tree in data structures, you will see why you need a tree in
data structures.
The Necessity for a Tree in Data Structures
Other data structures like arrays, linked-list, stacks, and queues are linear data structures, and
all these data structures store data in sequential order. Time complexity increases with
increasing data size to perform operations like insertion and deletion on these linear data
structures. But it is not acceptable for today's world of computation.
The non-linear structure of trees enhances the data storing, data accessing, and manipulation
processes by employing advanced control methods traversal through it. You will learn about
tree traversal in the upcoming section.
But before that, understand the tree terminologies.
Tree Node
A node is a structure that contains a key or value and pointers in its child node in the tree data
structure.
In the tree data structure, you can define the tree node as follows.

struct node
{
int data;
struct node *leftchild;
struct node *rightchild;

Page. 20
}

Continuing with this tutorial, you will see some key terminologies of the tree in data structures.

Types of Tree in Data Structures


Here are the different kinds of tree in data structures:
➢ General Tree
➢ Binary Tree
➢ Binary Search Tree
➢ Red Black Tree
➢ AVL Tree

Graphs

A graph is a non-linear kind of data structure made up of nodes or vertices and edges. The
edges connect any two nodes in the graph, and the nodes are also known as vertices.

This graph has a set of vertices V= { 1,2,3,4,5} and a set of edges E= {


(1,2),(1,3),(2,3),(2,4),(2,5),(3,5),(4,50 }.
Now that you’ve learned about the definition of graphs in data structures, you will learn about
their various types.
Types of Graphs in Data Structures
Page. 21
There are different types of graphs in data structures, each of which is detailed below.
➢ Finite Graph
➢ Infinite Graph
➢ Trivial Graph
➢ Simple Graph
➢ Multi Graph
➢ Null Graph
➢ Complete Graph
➢ Pseudo Graph
➢ Regular Graph
➢ Weighted Graph
➢ Directed Graph
➢ Undirected Graph
➢ Connected Graph
➢ Disconnected Graph
➢ Cyclic Graph
➢ Acyclic Graph
➢ Directed Acyclic Graph
➢ Subgraph

Representation of Graphs in Data Structures


Graphs in data structures are used to represent the relationships between objects. Every graph
consists of a set of points known as vertices or nodes connected by lines known as edges. The
vertices in a network represent entities.
The most frequent graph representations are the two that follow:
Adjacency matrix
Adjacency list
You’ll look at these two representations of graphs in data structures in more detail:

Adjacency Matrix
A sequential representation is an adjacency matrix.
It's used to show which nodes are next to one another. I.e., is there any connection between
nodes in a graph?
You create an MXM matrix G for this representation. If an edge exists between vertex a and
vertex b, the corresponding element of G, gi,j = 1, otherwise gi,j = 0.
If there is a weighted graph, you can record the edge's weight instead of 1s and 0s.
Undirected Graph Representation

Page. 22
Directed Graph Representation

Weighted Undirected Graph Representation


Weight or cost is indicated at the graph's edge, a weighted graph representing these values in
the matrix.

Adjacency List
A linked representation is an adjacency list.
You keep a list of neighbors for each vertex in the graph in this representation. It means that
each vertex in the graph has a list of its neighboring vertices.
You have an arra of vertices indexed by the vertex number, and the
corresponding array member for each vertex x points to a singly linked list of x's neighbors.
Weighted Undirected Graph Representation Using Linked-List

Page. 23
Weighted Undirected Graph Representation Using an Array

Graph Traversal Algorithm -


Breadth-First Search or BFS
BFS is a search technique for finding a node in a graph data structure that meets a set of
criteria.
It begins at the root of the graph and investigates all nodes at the current depth level before
moving on to nodes at the next depth level.
To maintain track of the child nodes that have been encountered but not yet inspected, more
memory, generally you require a queue.
Algorithm of breadth-first search
Step 1: Consider the graph you want to navigate.
Step 2: Select any vertex in your graph, say v1, from which you want to traverse the graph.
Step 3: Examine any two data structures for traversing the graph.
Visited array (size of the graph)
Queue data structure
Step 4: Starting from the vertex, you will add to the visited array, and afterward, you will v1's
adjacent vertices to the queue data structure.

Page. 24
Step 5: Now, using the FIFO concept, you must remove the element from the queue, put it into
the visited array, and then return to the queue to add the adjacent vertices of the removed
element.
Step 6: Repeat step 5 until the queue is not empty and no vertex is left to be visited.

Depth-First Search or DFS


DFS is a search technique for finding a node in a graph data structure that meets a set of
criteria.
The depth-first search (DFS) algorithm traverses or explores data structures such as trees and
graphs. The DFS algorithm begins at the root node and examines each branch as far as feasible
before backtracking.
To maintain track of the child nodes that have been encountered but not yet inspected, more
memory, generally a stack, is required.
Algorithm of depth-first search
Step 1: Consider the graph you want to navigate.
Step 2: Select any vertex in our graph, say v1, from which you want to begin traversing the
graph.
Step 3: Examine any two data structures for traversing the graph.
Visited array (size of the graph)
Stack data structure
Step 4: Insert v1 into the array's first block and push all the adjacent nodes or vertices of vertex
v1 into the stack.
Step 5: Now, using the FIFO principle, pop the topmost element and put it into the visited
array, pushing all of the popped element's nearby nodes into it.
Step 6: If the topmost element of the stack is already present in the array, discard it instead of
inserting it into the visited array.
Step 7: Repeat step 6 until the stack data structure isn't empty.

Page. 25
Conclusion
In conclusion, data structures are a great tool to computer science and the professionals who
utilize them. Data structures have their advantages and disadvantages like everything in our
lives. Only advance users can make changes to data structures, and any problem involving data
structure will need a professional to rectify. Luckily, there are more advantages than there are
disadvantages. Data structures allow information storage, it provides the means for
management of large data like databases, work together and are necessary for efficient
algorithms, safe storage of data, allows easier processing of data, and the use of the internet to
access data anytime. With those odds, this makes it easy to accept that without these
applications in our lives, life would be that much harder when dealing with computer science
and even our day to day tasks.
References

https://trainings.internshala.com/
https://www.simplilearn.com/
https://www.javatpoint.com/
https://www.geeksforgeeks.org

Page. 26

You might also like