UNit 1
UNit 1
A data structure is not only used for organizing the data. It is also used for processing, retrieving, and storing data.
Different basic and advanced types of data structures are used in almost every program or software system that has be
developed. So we must have good knowledge of data structures.
Non-linear data structure: Data structures where data elements are not placed sequentially or linearly are calle
non-linear data structures. In a non-linear data structure, we can’t traverse all the elements in a single run only
Examples of non-linear data structures are trees and graphs.
Need Of Data structure :
The structure of the data and the synthesis of the algorithm are relative to each other. Data presentation must be easy t
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.
1. Data structure modification is easy.
2. It requires less time.
3. Save storage memory space.
4. Data representation is easy.
5. Easy access to the large database.
A. Arrays:
An array is a linear data structure and it is a collection of items stored at contiguous memory locations. The idea is to
store multiple items of the same type together in one place. It allows the processing of a large amount of data in a
relatively short period. The first element of the array is indexed by a subscript of 0. There are different operations
possible in an array, like Searching, Sorting, Inserting, Traversing, Reversing, and Deleting.
Characteristics of an Array:
An array has various characteristics which are as follows:
Arrays use an index-based data structure which helps to identify each of the elements in an array easily using
index.
If a user wants to store multiple values of the same data type, then the array can be utilized efficiently.
An array can also handle complex data structures by storing data in a two-dimensional array.
An array is also used to implement other data structures like Stacks, Queues, Heaps, Hash tables, etc.
The search process in an array can be done very easily.
Operations performed on array:
Initialization: An array can be initialized with values at the time of declaration or later using an assignment
statement.
Accessing elements: Elements in an array can be accessed by their index, which starts from 0 and goes up to t
size of the array minus one.
Searching for elements: Arrays can be searched for a specific element using linear search or binary search
algorithms.
Sorting elements: Elements in an array can be sorted in ascending or descending order using algorithms like
bubble sort, insertion sort, or quick sort.
Inserting elements: Elements can be inserted into an array at a specific location, but this operation can be time
consuming because it requires shifting existing elements in the array.
Deleting elements: Elements can be deleted from an array by shifting the elements that come after it to fill the
gap.
Updating elements: Elements in an array can be updated or modified by assigning a new value to a specific in
Traversing elements: The elements in an array can be traversed in order, visiting each element once.
These are some of the most common operations performed on arrays. The specific operations and algorithms used ma
vary based on the requirements of the problem and the programming language used.
Applications of Array:
Different applications of an array are as follows:
B. Linked list:
A linked list is a linear data structure in which elements are not stored at contiguous memory locations. The elements
linked list are linked using pointers as shown in the below image:
Singly-linked list
Doubly linked list
Circular linked list
Doubly circular linked list
Initialization: A linked list can be initialized by creating a head node with a reference to the first node. Each
subsequent node contains a value and a reference to the next node.
Inserting elements: Elements can be inserted at the head, tail, or at a specific position in the linked list.
Deleting elements: Elements can be deleted from the linked list by updating the reference of the previous node
point to the next node, effectively removing the current node from the list.
Searching for elements: Linked lists can be searched for a specific element by starting from the head node and
following the references to the next nodes until the desired element is found.
Updating elements: Elements in a linked list can be updated by modifying the value of a specific node.
Traversing elements: The elements in a linked list can be traversed by starting from the head node and followi
the references to the next nodes until the end of the list is reached.
Reversing a linked list: The linked list can be reversed by updating the references of each node so that they po
to the previous node instead of the next node.
These are some of the most common operations performed on linked lists. The specific operations and algorith
used may vary based on the requirements of the problem and the programming language used.
C. Stack:
Stack is a linear data structure that follows a particular order in which the operations are performed. The order is
LIFO(Last in first out). Entering and retrieving data is possible from only one end. The entering and retrieving of data
also called push and pop operation in a stack. There are different operations possible in a stack like reversing a stack
using recursion, Sorting, Deleting the middle element of a stack, etc
Characteristics of a Stack:
Stack has various different characteristics which are as follows:
Stack is used in many different algorithms like Tower of Hanoi, tree traversal, recursion, etc.
Stack is implemented through an array or linked list.
It follows the Last In First Out operation i.e., an element that is inserted first will pop in last and vice versa.
The insertion and deletion are performed at one end i.e. from the top of the stack.
In stack, if the allocated space for the stack is full, and still anyone attempts to add more elements, it will lead to stack
overflow.
Applications of Stack:
Different applications of Stack are as follows:
The stack data structure is used in the evaluation and conversion of arithmetic expressions.
It is used for parenthesis checking.
While reversing a string, the stack is used as well.
Stack is used in memory management.
It is also used for processing function calls.
The stack is used to convert expressions from infix to postfix.
The stack is used to perform undo as well as redo operations in word processors.
The stack is used in virtual machines like JVM.
The stack is used in the media players. Useful to play the next and previous song.
The stack is used in recursion operations.
Operation performed on stack ;
A stack is a linear data structure that implements the Last-In-First-Out (LIFO) principle. Here are some common
operations performed on stacks:
Push: Elements can be pushed onto the top of the stack, adding a new element to the top of the stack.
Pop: The top element can be removed from the stack by performing a pop operation, effectively removing the
element that was pushed onto the stack.
Peek: The top element can be inspected without removing it from the stack using a peek operation.
IsEmpty: A check can be made to determine if the stack is empty.
Size: The number of elements in the stack can be determined using a size operation.
These are some of the most common operations performed on stacks. The specific operations and algorithms used ma
vary based on the requirements of the problem and the programming language used. Stacks are commonly used in
applications such as evaluating expressions, implementing function call stacks in computer programs, and many other
D. Queue:
Queue is a linear data structure that follows a particular order in which the operations are performed. The order is Firs
First Out(FIFO) i.e. the data item stored first will be accessed first. In this, entering and retrieving data is not done fro
only one end. An example of a queue is any queue of consumers for a resource where the consumer that came first is
served first. Different operations are performed on a Queue like Reversing a Queue (with or without using recursion),
Reversing the first K elements of a Queue, etc. A few basic operations performed In Queue are enqueue, dequeue, fro
rear, etc
Characteristics of a Queue:
The queue has various different characteristics which are as follows:
Enqueue: Elements can be added to the back of the queue, adding a new element to the end of the queue.
Dequeue: The front element can be removed from the queue by performing a dequeue operation, effectively
removing the first element that was added to the queue.
Peek: The front element can be inspected without removing it from the queue using a peek operation.
IsEmpty: A check can be made to determine if the queue is empty.
Size: The number of elements in the queue can be determined using a size operation.
These are some of the most common operations performed on queues. The specific operations and algorithms used m
vary based on the requirements of the problem and the programming language used. Queues are commonly used in
applications such as scheduling tasks, managing communication between processes, and many others.
Characteristics of a Tree:
The tree has various different characteristics which are as follows:
A tree is also known as a Recursive data structure.
In a tree, the Height of the root can be defined as the longest path from the root node to the leaf node.
In a tree, one can also calculate the depth from the top to any node. The root node has a depth of 0.
Applications of Tree:
Different applications of Tree are as follows:
Heap is a tree data structure that is implemented using arrays and used to implement priority queues.
B-Tree and B+ Tree are used to implement indexing in databases.
Syntax Tree helps in scanning, parsing, generation of code, and evaluation of arithmetic expressions in Compi
design.
K-D Tree is a space partitioning tree used to organize points in K-dimensional space.
Spanning trees are used in routers in computer networks.
Operation performed on tree:
A tree is a non-linear data structure that consists of nodes connected by edges. Here are some common operations
performed on trees:
Insertion: New nodes can be added to the tree to create a new branch or to increase the height of the tree.
Deletion: Nodes can be removed from the tree by updating the references of the parent node to remove the
reference to the current node.
Search: Elements can be searched for in a tree by starting from the root node and traversing the tree based on
value of the current node until the desired node is found.
Traversal: The elements in a tree can be traversed in several different ways, including in-order, pre-order, and
post-order traversal.
Height: The height of the tree can be determined by counting the number of edges from the root node to the
furthest leaf node.
Depth: The depth of a node can be determined by counting the number of edges from the root node to the curr
node.
Balancing: The tree can be balanced to ensure that the height of the tree is minimized and the distribution of
nodes is as even as possible.
These are some of the most common operations performed on trees. The specific operations and algorithms used may
vary based on the requirements of the problem and the programming language used. Trees are commonly used in
applications such as searching, sorting, and storing hierarchical data.
F. Graph:
A graph is a non-linear data structure that consists of vertices (or nodes) and edges. It consists of a finite set of vertice
and set of edges that connect a pair of nodes. The graph is used to solve the most challenging and complex programm
problems. It has different terminologies which are Path, Degree, Adjacent vertices, Connected components, etc.
Characteristics of Graph:
The graph has various different characteristics which are as follows:
The maximum distance from a vertex to all the other vertices is considered the Eccentricity of that ver
The vertex having minimum Eccentricity is considered the central point of the graph.
The minimum value of Eccentricity from all vertices is considered the radius of a connected graph.
Applications of Graph:
Different applications of Graphs are as follows:
Primitive data types are the basic building blocks for data manipulation in programming languages. They typically
include:
----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----
these data types are defined by default in the Programming languages type system, they come with a set of predef
operations. Such primitive types cannot have new operations defined. There are three more types of primitives in the
type system:
1. Short, int, long, float, and double are the numerical primitives. These primitive data types can only store numb
Simple arithmetic (addition, subtraction, etc.) or comparison operations are associated with such data types (gre
than, equal to, etc.)
2. Textual primitives include bytes and characters. Characters are stored in these primitive data types (that ca
Unicode alphabets or even numbers). Textual manipulation operations are associated with data types (compa
two words, joining characters to make words, etc.). However, byte and char can perform arithmetic operation
well.
3. Primitives with boolean and null values: boolean and null.
The actual number of primitive data types available is determined by the programming language that is used. Strings
instance, are a composite but built-in data type in C#, even as they are integrated to a primitive data type that is both b
and built-in in advanced accents of BASIC and JavaScript.
Considering the Java Programming language, the primitive data structures include integers, floats, characters, and poin
In general, there are 8 data types. They are as follows
A Boolean data type comprises a single bit of information that can only store true or false values. True or false condit
are tracked using this data type, and Boolean data types are also used to store the result of various conditions. Let's wr
small program and see how it works.
1. class booleanDataType{
2. public static void main(String args[]){
3. // Setting the values for boolean data type
4. boolean Java = true;
5. boolean Python = false;
6. System.out.println(Java); // Output will be true
7. System.out.println(Python); // Output will be false
8. }
9. }
Byte Data Type
The byte data type is an illustration of a primitive data type. It is a signed two's complement integer of 8 bits, and it st
whole numbers ranging from -128 to 127. A byte data type is useful for saving large amounts of memory. Let's wr
small program and see how it works.
1. class ByteExample {
2. public static void main(String[] args) {
3. byte n, a;
4. n = 127;
5. a=177;
6. System.out.println(n); // prints 127
7. System.out.println(a); // throws an error because it cannot store more than 127 bits
8. }
9. }
Char Data Type
A single character is stored in this data type, and the character must be enclosed in single quotes, such as 'E' or 'e'. You
also use ASCII values to display specific characters. Let's look at a simple example to see how it works.
A short data type is larger than a byte but smaller than an integer, and it saves values ranging from -32,768 to 32767.
data type's default size is 2 bytes. Let's look at an example to understand the short data type better.
This data type is capable of storing whole numbers ranging from -2147483648 to 2147483647. When creating varia
with numeric values, int is generally the preferred data type.
This data type is a two's complement 64-bit integer. A long data type's default size is 64 bits, and its value ranges fr
263 to 263-1.
It would be best to use a floating-point type when you need a number with a decimal, such as 8.88 or 3.14515.
This data type supports fractional numbers ranging from 3.4e038 to 3.4e+038. It is important to note that the value sh
end with an "f." Let's look at a specific example to understand this data type better.
The double data type can store fractional numbers from 1.7e-308 to 1.7e+308. Note that you should end the value w
"d":
Examples of ADTs
List ADT: Collection of elements with operations to insert, delete, and access elements.
Stack ADT: Collection of elements with LIFO access.
Queue ADT: Collection of elements with FIFO access.
----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----
List ADT
Lists are linear data structures that hold data in a non-continuous structure. The list is made up of data storage contain
known as "nodes." These nodes are linked to one another, which means that each node contains the address of anothe
block. All of the nodes are thus connected to one another via these links.
Some of the most essential operations defined in List ADT are listed below.
front(): returns the value of the node present at the front of the list.
back(): returns the value of the node present at the back of the list.
push_front(int val): creates a pointer with value = val and keeps this pointer to the front of the linked list.
push_back(int val): creates a pointer with value = val and keeps this pointer to the back of the linked list.
size(): returns the number of nodes that are present in the list.
Stack ADT
A stack is a linear data structure that only allows data to be accessed from the top. It simply has two operations: push
insert data to the top of the stack) and pop (to remove data from the stack). (used to remove data from the stack top).
Some of the most essential operations defined in Stack ADT are listed below.
top(): returns the value of the node present at the top of the stack.
push(int val): creates a node with value = val and puts it at the stack top.
size(): returns the number of nodes that are present in the stack.
Queue ADT
A queue is a linear data structure that allows data to be accessed from both ends. There are two main operations in the
queue: push (this operation inserts data to the back of the queue) and pop (this operation is used to remove data from
front of the queue).
Some of the most essential operations defined in Queue ADT are listed below.
front(): returns the value of the node present at the front of the queue.
back(): returns the value of the node present at the back of the queue.
push(int val): creates a node with value = val and puts it at the front of the queue.
size(): returns the number of nodes that are present in the queue.
Provides abstraction, which simplifies the complexity of the data structure and allows users to focus on the
functionality.
Enhances program modularity by allowing the data structure implementation to be separate from the rest of th
program.
Enables code reusability as the same data structure can be used in multiple programs with the same interface.
Promotes the concept of data hiding by encapsulating data and operations into a single unit, which enhances
security and control over the data.
Supports polymorphism, which allows the same interface to be used with different underlying data structures, providi
flexibility and adaptability to changing requirements.
Overhead: Using ADTs may result in additional overhead due to the need for abstraction and encapsulation.
Limited control: ADTs can limit the level of control that a programmer has over the data structure, which can be a
disadvantage in certain scenarios.
Performance impact: Depending on the specific implementation, the performance of an ADT may be lower than tha
a custom data structure designed for a specific application.
----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----*----
The word Algorithm means ” A set of finite rules or instructions to be followed in calculations or other problem-solv
operations ”
Or
” A procedure for solving a mathematical problem in a finite number of steps that frequently involves recursive
operations”.
Computer Science: Algorithms form the basis of computer programming and are used to solve problems rangi
from simple sorting and searching to complex tasks such as artificial intelligence and machine learning.
Mathematics: Algorithms are used to solve mathematical problems, such as finding the optimal solution to a
system of linear equations or finding the shortest path in a graph.
Operations Research: Algorithms are used to optimize and make decisions in fields such as transportation,
logistics, and resource allocation.
Artificial Intelligence: Algorithms are the foundation of artificial intelligence and machine learning, and are u
to develop intelligent systems that can perform tasks such as image recognition, natural language processing,
decision-making.
Data Science: Algorithms are used to analyze, process, and extract insights from large amounts of data in field
such as marketing, finance, and healthcare.
Clear and Unambiguous: The algorithm should be unambiguous. Each of its steps should be clear in all aspects and m
lead to only one meaning.
Well-Defined Inputs: If an algorithm says to take inputs, it should be well-defined inputs. It may or may not take inpu
Well-Defined Outputs: The algorithm must clearly define what output will be yielded and it should be well-defined a
well. It should produce at least 1 output.
Finite-ness: The algorithm must be finite, i.e. it should terminate after a finite time.
Feasible: The algorithm must be simple, generic, and practical, such that it can be executed with the available resourc
It must not contain some future technology or anything.
Language Independent: The Algorithm designed must be language-independent, i.e. it must be just plain instructions
can be implemented in any language, and yet the output will be the same, as expected.
Input: An algorithm has zero or more inputs. Each that contains a fundamental operator must accept zero or more inp
Output: An algorithm produces at least one output. Every instruction that contains a fundamental operator must accep
zero or more inputs.
Definiteness: All instructions in an algorithm must be unambiguous, precise, and easy to interpret. By referring to any
the instructions in an algorithm one can clearly understand what is to be done. Every fundamental operator in instruct
must be defined without any ambiguity.
Finiteness: An algorithm must terminate after a finite number of steps in all test cases. Every instruction which contai
fundamental operator must be terminated within a finite amount of time. Infinite loops or recursive functions without
base conditions do not possess finiteness.
Effectiveness: An algorithm must be developed by using very basic, simple, and feasible operations so that one can tr
it out by using just paper and pencil.
Properties of Algorithm:
It should terminate after a finite time.
It should produce at least one output.
It should take zero or more input.
It should be deterministic means giving the same output for the same input case.
Every step in the algorithm must be effective i.e. every step should do some work.
Types of Algorithms:
There are several types of algorithms available. Some important algorithms are:
2. Recursive Algorithm:
A recursive algorithm is based on recursion. In this case, a problem is broken into several sub-parts and called the sam
function again and again.
3. Backtracking Algorithm:
The backtracking algorithm builds the solution by searching among all possible solutions. Using this algorithm, we ke
on building the solution following criteria. Whenever a solution fails we trace back to the failure point build on the ne
solution and continue this process till we find the solution or all possible solutions are looked after.
4. Searching Algorithm:
Searching algorithms are the ones that are used for searching elements or groups of elements from a particular data
structure. They can be of different types based on their approach or the data structure in which the element should be
found.
5. Sorting Algorithm:
Sorting is arranging a group of data in a particular manner according to the requirement. The algorithms which help in
performing this function are called sorting algorithms. Generally sorting algorithms are used to sort groups of data in
increasing or decreasing manner.
6. Hashing Algorithm:
Hashing algorithms work similarly to the searching algorithm. But they contain an index with a key ID. In hashing, a
is assigned to specific data.
Divide
Solve
Combine
8. Greedy Algorithm:
In this type of algorithm, the solution is built part by part. The solution for the next part is built based on the immedia
benefit of the next part. The one solution that gives the most benefit will be chosen as the solution for the next part.
9. Dynamic Programming Algorithm:
This algorithm uses the concept of using the already found solution to avoid repetitive calculation of the same part of
problem. It divides the problem into smaller overlapping subproblems and solves them.
Advantages of Algorithms:
It is easy to understand.
An algorithm is a step-wise representation of a solution to a given problem.
In an Algorithm the problem is broken down into smaller pieces or steps hence, it is easier for the programme
convert it into an actual program.
Disadvantages of Algorithms:
Writing an algorithm takes a long time so it is time-consuming.
Understanding complex logic through algorithms can be very difficult.
Branching and Looping statements are difficult to show in Algorithms(imp).
How to Design an Algorithm?
To write an algorithm, the following things are needed as a pre-requisite:
The problem that is to be solved by this algorithm i.e. clear problem definition.
The constraints of the problem must be considered while solving the problem.
The input to be taken to solve the problem.
The output is to be expected when the problem is solved.
The solution to this problem is within the given constraints
algorithm design tools: pseudo code and flowchart, relationship among data
Algorithm, Pseudocode, Programs, and Flowcharts
Algorithm: An algorithm is a step-by-step procedure for solving a computational problem. It is a process or set of rul
be followed in calculations or other problem-solving operations.
Program: A program is a step-by-step machine instruction used for solving any problem or computational task
The terminal is an oval that indicates the beginning and end of a program. It usually contains the words Start or End.
Flowline
The flowline is a line from one symbol pointing towards another to show the process’s order of operation. This displa
the flow of execution in a program.
Input/Output
Input/output is represented by a rhomboid and indicates the input or output of data. This is similar to setting a value to
variable.
Process
A process, represented by a rectangle, is an operation that manipulates data. Think of this as changing the value of a
number-based variable using an operator such as +.
Decision
Decisions are represented by a rhombus and show a conditional operation that will determine which path a program
should take. This is similar to conditional statements which control the flow of execution in a program
Flowchart for adding two numbers
. No Algorithm Flowchart
3. In the algorithm, plain text is used. In the flowchart, symbols/shapes are used.
There are no rules to writing algorithms There are certain rules for writing pseudocode
Algorithms can be considered pseudocode Pseudocode cannot be considered an algorithm
It is difficult to understand and interpret It is easy to understand and interpret
Flowchart Pseudocode
A Pseudocode is a step-by-step description of an
A Flowchart is pictorial representation of flow
algorithm in code like structure using plain English
of an algorithm.
text.
A Flowchart uses standard symbols for input,
output decisions and start stop statements. Pseudocode uses reserved keywords like if-else, for,
Only uses different shapes like box, circle and while, etc.
arrow.
This is a way of visually representing data,
These are fake codes as the word pseudo means
these are nothing but the graphical
fake, using code like structure but plain English text
representation of the algorithm for a better
instead of programming language
understanding of the code
Pseudocode is better suited for the purpose of
Flowcharts are good for documentation
understanding
6. Efficient Program Maintenance: The maintenance of operating program becomes easy with the help of flowchart
helps the programmer to put efforts more efficiently on that part
Advantages:
· Logic Flowcharts are easy to understand.They provide a graphical representation of actions to be taken.
· Logic Flowcharts are well suited for representing logic where there is intermingling among many actions.
Disadvantages:
· Logic Flowcharts may encourage the use of GoTo statements leadingsoftware design that is unstructured with l
that is difficult to decipher.
· Without an automated tool, it is time-consuming to maintain Logic Flowcharts.
· Logic Flowcharts may be used during detailed logic design to specify a module.
· However, the presence of decision boxes may encourage the use of GoTo statements, resulting in software that
not structured. For this reason, Logic Flowcharts may be better used during Structural Design
Pseudo Code
Pseudo code is a high-level description of an algorithm that uses the conventions of programming languages but with
strict syntax rules. It helps in understanding and planning algorithms before actual coding.
Now that we have the entire algorithm thought out and in visual form, we can take steps to turn it into code. Some peo
may be able to jump right into a development environment and start hacking away, but let’s take it slow and create so
pseudocode first.
Pseudocode is a description of an algorithm using everyday wording, but molded to appear similar to a simplified
programming language.
To create pseudocode from what we have so far we can use the flowchart’s flowlines to guide the structure of our cod
we simplify the steps we outlined earlier:
define password
create a pass_length variable and set it to 0
create a contains_number variable and set it to False
if the entire password hasn't been searched:
iterate to the next character of the password
increment the pass_length variable
if the current character of the password contains number:
set contains_number to True
if pass_length is greater than 8 and if contain_number is equal to True:
valid password
otherwise:
invalid password
The final code
Now the closing moments! With pseudocode in hand, the algorithm can be programmed in any language. Here it is
in Python:
Advantages of Pseudocode
Improves the readability of any approach. It’s one of the best approaches to start implementation of an
algorithm.
Acts as a bridge between the program and the algorithm or flowchart. Also works as a rough
documentation, so the program of one developer can be understood easily when a pseudo code is written
out. In industries, the approach of documentation is essential. And that’s where a pseudo-code proves v
The main goal of a pseudo code is to explain what exactly each line of a program should do, hence maki
the code construction phase easier for the programmer.
The relationship among data elements can be defined through their organization in data structures. Different data
structures model relationships in various ways:
Linear Relationships
Arrays: Elements have a direct relationship, with each element being adjacent to the next.
Linked Lists: Each element (node) points to the next, forming a chain.
Hierarchical Relationships
Trees: Represent hierarchical relationships with a parent-child structure.
o Binary Tree: Each node has at most two children.
Network Relationships
Graphs: Represent complex relationships where nodes (vertices) can be connected by edges in various ways.
o Directed Graph: Edges have directions.
o Undirected Graph: Edges do not have directions.
Algorithm
BEGIN
Pseudo Code
// Step 1: Declare variables
DECLARE integer a, b, sum
END
#include <stdio.h>
int main() {
// Step 1: Declare variables
int a, b, sum;
return 0;
}
Example 2: Python Programming Language – Sum of Two Numbers
Component Description
Problem Find the sum of two numbers (e.g., 10 and 7)
1. Start
2. Define variables a and b
3. Assign values: a = 10, b = 7
4. Compute sum = a + b
5. Print the result
6. End
Algorithm
BEGIN
# Step 1: Define variables
SET a = 10
Pseudo Code
SET b = 7
END
# Step 1: Assign values to variables
a = 10
b=7
Program
# Step 2: Perform addition
(Python) sum = a + b
Explanation:
Lower Bound:
Represents the minimum amount of time or space an algorithm must take to complete, given any input of a
certain size.
Often expressed using Big Omega notation, which provides an asymptotic lower bound.
For example, an algorithm with a lower bound of Ω(n log n) suggests that it cannot be solved faster than a
logarithmic-linear function in the best-case or average-case scenario.
In essence:
The upper bound provides a guarantee on the maximum resource consumption, while the lower bound indica
the minimum resource usage.
Knowing both the upper and lower bounds can help in selecting the most appropriate algorithm for a specific
task or in understanding the inherent limitations of solving a problem.
What is Complexity?
Complexity refers to the resources required by an algorithm, typically time and space. It measures how these resource
grow with the size of the input.
Types of Complexity
1. Time Complexity: The amount of time an algorithm takes to complete.
2. Space Complexity: The amount of memory an algorithm uses during its execution.
3. Best case complexity: The best-case scenario for an algorithm is the scenario in which the algorithm performs
minimum amount of work (e.g. takes the shortest amount of time, uses the least amount of memory, etc.).
4. Worst case complexity: The worst-case scenario for an algorithm is the scenario in which the algorithm perfor
the maximum amount of work (e.g. takes the longest amount of time, uses the most amount of memory, etc.).
Time Complexity
Example: An algorithm with a time complexity of O(n) will take linear time relative to the input size.
Space Complexity
Example: An algorithm with a space complexity of O(n) will use linear memory relative to the input size.
Asymptotic Analysis
Asymptotic analysis is used to describe the behavior of an algorithm as the input size grows. It provides a high-level
understanding of the algorithm's efficiency.
Asymptotic Notations
1. Big O Notation (O): Describes the upper bound of an algorithm's running time. It represents the worst-case
scenario.
o Example: O(n), O(log n), O(n^2).
2. Omega Notation (Ω): Describes the lower bound of an algorithm's running time. It represents the best-case
scenario.
o Example: Ω(n), Ω(log n), Ω(n^2).
3. Theta Notation (Θ): Describes the tight bound of an algorithm's running time. It represents both the best and
worst-case scenarios.
o Example: Θ(n), Θ(log n), Θ(n^2).
Big O Notation
O(1): Constant time.
O(n): Linear time.
O(n^2): Quadratic time.
O(g(n)) = {f(n): there exist positive constants c0 and c1 such that 0 ≤ f(n) ≤ c0g(n) for all n ≥ c1}.
For Example:
Let, f(n) = n2 + n + 1
g(n) = n2
n2 + n + 1 <= c (n2)
The time complexity of the above function is O(n2 ), because the above function has to run for n2 time at least.
Omega Notation(Ω)
Omega notation is used to denote the lower bound of the algorithm; it represents the minimum running time of an
algorithm. Therefore, it provides the best-case complexity of any algorithm.
Ω(g(n)) = {f(n): there exist positive constants c0 and c1, such that 0 ≤ c0g(n) ≤ f(n) for all n ≥ c1}.
For Example:
Let,
f(n) = n2 + n
Then, the best-case time complexity will be Ω(n2)
f(n) = 100n + log(n)
Θ(g(n)) = {f(n): there exist positive constants c0, c1 and c2, such that 0 ≤ c0g(n) ≤ f(n) ≤ c1g(n) for all n ≥ c2}
Difference Between Big O Notation, Omega Notation, and Theta Notation
Parameter Big O Notation (O) Omega Notation (Ω) Theta Notation (Θ)
It is commonly used to
Usage in Used to demonstrate Used to provide a precise
analyze efficiency,
Algorithm the effectiveness under analysis of algorithm efficiency
especially concerning
Analysis optimal conditions. in typical scenarios.
worst-case performance.