FDS Unit 1 Notes
FDS Unit 1 Notes
Unit – I
Introduction to Algorithm and Data
Structures
1. Introduction
1. Problem: A real-world challenge or task that needs solving (e.g., sorting a list of
numbers).
2. Solution: The conceptual approach or plan to solve the problem, including identifying
the necessary operations.
4. Data Structure: The organization and storage of data used by the algorithm (e.g.,
arrays, linked lists, trees).
This process ensures a logical flow from understanding the problem to writing a program that
solves it efficiently.
A data structure is a way of organizing, managing, and storing data in a computer so it can be
accessed and modified efficiently.
Example: Consider a set of elements that can be stored in an array data structure. The
representation of the array containing set of elements is as follows:
2|Page
An Abstract Data Type (ADT) is a theoretical concept that defines a data type purely in terms
of its behavior (operations) rather than its implementation. It describes what operations can be
performed, not how they are implemented. ADTs provide a blueprint for data structures by
focusing on functionality and hiding implementation details.
declare
CREATE() → array
The function RETRIEVE() takes as input an array and an index, and either returns the
appropriate value of an error.
3|Page
Linear data structures are the data structures in which data s arranged in a list or in a straight
sequence.
Non-linear data structures are the data structures in which data may be arranged in a
hierarchical manner.
The static data structures are data structures having fixed size memory utilization. One has to
allocate the size of this data structure before using it.
Example: Arrays in C are a static data structure. We first allocate the size of the arrays before
its actual use. Sometimes the size we have allocated for the arrays might be wasted or we may
require a larger size than the one which is existing. Thus, the data structure is static in nature.
The dynamic data structure is a data structure in which one can allocate the memory as per his
requirement. If one does not want to use some block of memory, he can deallocate it.
4|Page
Example: A linked list is a collection of many nodes. Each node consists of data and pointer
to next node. In linked list, the user can create as many nodes (memory) as he wants, he can
deallocate the memory which cannot be utilized further. The advantage of dynamic data
structure over the static data structure is that there is no wastage of memory.
A persistent data structure is a data structure that can be accessed but cannot be modified.
Any operation on such data structure creates two versions of data structures. Previous version
is saved and all changes are made in the new version.
An ephemeral data structure is a data structure that only allows one version to be available
at a time.
When an update is made to an ephemeral data structure, the previous version is lost.
2. Algorithms
1. Identify the problem: Identifying the problem is the first step in solving the problem.
Problem identification is very essential before solving any problem.
2. Understand the problem: Before solving any problem, it is important to understand
it. There are three aspects based on which the problem can be understood.
Knowledgebase: While solving the problem, the knowledgebase can be related
to a person or a machine. If the problem is to be solved for a person, then it is
necessary to know what a person knows.
Subject: Before solving the problem, the subject or the topic on which the
problem is based must be known. For example, to solve a problem involving
Laplace Transformation, it is necessary to first know about Laplace
Transformation.
5|Page
The word algorithm means “a set of finite rules or instructions to be followed in calculations
or other problem-solving operations”.
6|Page
Characteristics of Algorithms:
Clear and Unambiguous: The algorithm should be unambiguous. Each of its steps
should be clear in all aspects and must lead to only one meaning.
Finiteness: The algorithm must be finite, i.e. it should terminate after a finite time.
Step 1: Start
Step 2: Input the number 'num'.
Step 3: Initialize 'sum' to 0.
Step 4: While 'num' is greater than 0, repeat steps 5 to 7:
Step 5: Extract the last digit of 'num' using:
digit = num % 10
Step 6: Add 'digit' to 'sum':
sum = sum + digit
Step 7: Remove the last digit from 'num' by performing integer
division:
num = num // 10
Step 8: Output 'sum' (the sum of the digits).
Step 9: Stop.
For example, for the number 543:
5 + 4 + 3 = 12, so the algorithm returns 12.
2.4 Algorithm Design Tools
1. Pseudocode
7|Page
Pseudocode is the intermediate state between an idea and its implementation(code) in a high-
level language.
1. Start
2. Input n (the number to find the factorial of)
3. Initialize factorial = 1
4. If n < 0:
a. Output "Factorial is not defined for negative numbers"
b. Stop
5. For i = 1 to n:
a. factorial = factorial * i
6. Output factorial
7. Stop
2. Flowchart
A flowchart is a type of diagram that represents a workflow or process. A flowchart can also
be defined as a diagrammatic representation of an algorithm, a step-by-step approach to solving
a task.
3. Complexity of Algorithm
The space complexity can be defined as amount of memory required by an algorithm to run.
To compute the space complexity, we use two factors: constant and instance characteristics.
S(p) = C + Sp
where C is a constant i.e. fixed part and it denotes the space of inputs and outputs. This space
is an amount of space taken by instruction, variables and identifiers. And Sp is a space
dependent upon instance characteristics. This is a variable part whose space requirement
depends on particular problem instance.
9|Page
The amount of time required by an algorithm to execute is called the time complexity of that
algorithm.
For determining the time complexity of a particular algorithm, following steps are carried out:
3. Consider the order of magnitude of the frequency count and express in terms of big oh
notation.
Asymptotic notations are mathematical tools used to describe the performance (time or space
complexity) of algorithms in terms of input size n, especially as the input grows large. They
help express how an algorithm's resource consumption grows with respect to input size.
Big-O notation describes the upper bound of the time complexity of an algorithm. It tells you
the worst-case scenario — how much time or space the algorithm will take in the worst
possible case as the input grows.
Definition: A function f(n) is said to be O(g(n)) if there exist constants c > 0 and n0 ≥ 0
such that:
This means f(n) will not grow faster than g(n) for large inputs.
Example: For a linear search through an array of n elements, the time complexity is
O(n). This means in the worst case; it will take at most linear time as the input size
grows.
Theta notation describes the tight bound of an algorithm. It tells you the exact asymptotic
behavior, meaning it represents both the upper bound (worst-case) and lower bound (best-case)
of the algorithm.
Definition: A function f(n) is said to be θ(g(n)) if there exist constants c1, c2 > 0 and
n0 ≥ 0 such that:
This means f(n) grows at the same rate as g(n) as the input grows large.
Example: For an algorithm that runs exactly n steps for an input of size n, the time
complexity is θ (n). This means that for large inputs, the time complexity is both upper-
and lower-bounded by a linear function.
Omega notation describes the lower bound of an algorithm. It tells you the best-case scenario
— the minimum time or space an algorithm will take as the input grows.
Definition: A function f(n) is said to be Ω(g(n)) if there exist constants c > 0 and n0 ≥ 0
such that:
This means f(n) will take at least g(n) time or space for large inputs.
Example: In a linear search, the best case occurs when the element is found in the first
position. The time complexity is Ω(1), meaning the algorithm will take constant time
in the best case.
The Step Count or the Frequency Count Method is a technique used to analyze the time
complexity of an algorithm by counting the number of individual steps or basic operations the
algorithm performs, relative to the size of its input. Each line of code or operation is assigned
a step count, and the total number of steps is then expressed as a function of the input size,
typically using Big-O notation.
2. Count the number of times each basic operation is executed as a function of the input
size (n).
12 | P a g e
Example:
int x = 0; …1
for (i = 0; i < n; i++) // Outer loop …(n+1)
{
for (j = n; j > i; j--) // Inner loop …n(n+1)
{
x = x + i + j; // Basic operation …n*n
}
}
f(n) = 1 + (n+1) + n(n+1) + (n*n)
f(n) = 2n2 + 2n + 2
The time complexity of algorithms is often categorized based on how the number of operations
grows relative to the input size n.
Description: The number of operations grows proportionally with the input size n.
For each new element in the input, the algorithm does a constant amount of additional
work.
Description: The number of operations grows proportionally to the cube of the input
size n. This happens when you have three nested loops, each iterating over n elements.
4. Algorithmic Strategies
Algorithm design strategy is a general approach by which many problems can be solved
algorithmically. These problems may belong to different areas of computing. Algorithmic
strategies are also called as algorithmic techniques or algorithmic paradigm.
14 | P a g e
If the sub problems are large enough, then divide and conquer is reapplied.
The generated sub problems are usually of same type as the original problem. Hence
sometimes recursive algorithms are used in divide and conquer strategy.
The merge sort is a sorting algorithm that uses the divide and conquer strategy. In this method,
division is dynamically carried out.
1. Divide: Partition array into two sub lists s1 and s2 with n/2 elements each.
2. Conquer: Then sort sub-lists s1 and s2.
3. Combine: Merge s1 and s2 in a unique sorted group.
In Greedy technique, the solution is constructed through a sequence of steps, each expanding
a partially constructed solution obtained so far, until a complete solution to the problem is
reached.
Djikstra's Algorithm is a popular algorithm for finding the shortest path using Greedy method.
This algorithm is called single source shortest path algorithm.
In this algorithm, for a given vertex called source, the shortest path to all other vertices is
obtained.
16 | P a g e
In this algorithm the main focus is not to find only one single path but to find the shortest paths
from any vertex to all other remaining vertices.
Now we will consider each vertex as a source and with shortest distance from this vertex to
every other remaining vertex. Let us start with vertex A.
But we have one shortest distance obtained from A to E and that is A – B – C – D – E with path
length = 4 + 1 + 3 = 8. Similarly other shortest paths can be obtained by choosing appropriate
source and destination.
Djikstra's Shortest path algorithm takes O(ElogV + VlogV) time, where E is the number of
edges and V is the number of vertices of a graph.