Sunteți pe pagina 1din 820

Data Structures & Algorithms

(CS2005)
Dr. Biri Arun
CSE, NIT Rourkela.

References:
1. Data Structures and Algorithm Analysis in C by Mark Allen Weiss.
2. An Introduction to Data Structures with Applications by Jean-Paul Trembly and Paul G. Sorenson.
3. Data Structures with C by Seymour Lipschutz.
How are students (Objects of Real World) represented in
the Teacher's Register?
Roll Number Name Date
1 John
2 Michael
3 Lily

How are customers represented in Registry of a Bank?


Account No. Name Address Mobile Signature
No.
110034 John House No.112, Street No.3, 9843332874
Green Park, South Delhi,
India
110035 Michael House No.102, Street No.1, 7843232832
Parliament Colony, South
Delhi, India
• So, Real world objects are represented in paper/book by
considering only some of its relevant features or
properties and non-relevant features are ignored.

• Student = {roll_no, name,date}

• This is called Abstraction.

• The abstracted attribute is measured and assigned with a


value that reflects its real condition (nature, state).
• This value is called Data.
What is Data?
• Data is a number (value) that represents the
quantity/quality (nature) of an attribute (property/feature)
of a physical or a conceptual entity.
• Ex. Height=1.57m, No. of students=40, Father’s name =
Ram.
• Data is obtained through measurement or evaluation (of
some-kind).
• To represent data, we need some mathematical model.

Some of the models to represent data are:


• Roman numbers (I, II, IV, V, VII…),
• Arabic/Decimal numbers (0,1,2…9),
• Binary numbers (0,1), etc.
• Roman numbers do not easily support fundamental
operations like addition, subtraction, multiplication etc.
• Binary numbers support these operations, but they are not
convenient for humans to use.
• Arabic numbers easily support these operations and
hence are commonly used by humans.
• So, using Arabic number system, data are represented
in notebooks/books using pen/pencil.
• Different types of attributes (properties) of a physical
or a conceptual entity exist in the real world.
• Some attributes exits as complete/whole units.
• Some attributes exits in parts.
• Some are very small, while some are very large.
• These different types of attributes are represented using
different numbers of the Arabic number system like whole
numbers, integer numbers, fractions (rational & irrational),
etc.
• Whole Numbers = {0,1,2,3,4…..}
• Integers = {……-3,-2,-1,0,1,2,3……}
• Rational Numbers = {1.5, 1.862,…} Real Numbers
• Irrational Numbers = {𝜋, 2, 𝑒, …}
• Now, in Computer Age, we want to represent the data
contained in notebooks/books in computer’s memory.
• Main memory is made of transistors & capacitors.
• Secondary memory is of magnetic/optical
disks/tapes.
Main memory (RAM) of a Computer
1 2 3 ……………………………………………………………………50……………………..…………………………………………100
1 2 3 …………………………………………………………50
Main memory (RAM) of a Computer
• Presence of charge represents bit 1
• Absence of charge represents bit 0
Main memory (RAM) of a Computer
• Presence of charge represents bit 1
• Absence of charge represents bit 0
Secondary memory of a Computer
• Magnetic bits of type N-S represents bit 1
• Magnetic bits of type S-N represents bit 0

Non-Magnetized Bits
of Magnetic Tape
Secondary memory of a Computer

S S N N N

N N S S S

0 1 1 1 1 0 1

↓ ↑ ↑ ↑ ↑ ↓ ↑
• So, Arabic numbers can be converted into Binary
numbers and can be conveniently represented &
stored in Computers!!!!!
• First, a real world entity is modeled using Arabic number
system
• Second, the model is converted into an Abstract Data
Type.
• That is, the model is converted into a Binary number.
• Abstract Data Type (ADT) is collection of a set of
values and a set of operations, without
emphasizing/considering/focusing the representation and
implementation details of the set of values & operations.
• Representation and implementation details of the set
of values & operations are hidden from the users.
• An user must be able to use an ADT without knowing
anything of its implementation details.

• ADT gives logical structure to the data.


• Following details are not considered in ADT:
• How many bits should be used to represent integer,
fractions & characters,
• Whether zero charge should represent bit 0 or
otherwise,
• Whether N-S magnetization should represent bit 0 or
otherwise,
• Order in which a sequence of bytes should be stored in
memory, etc.
Data Representation Process using Computer
Real
Mathematical
World Abstract Data Type (ADT)
Model
Object

Height
Arabic Number Binary Number System, without
of a
System implementation details
Person

Height
of a (1.75m)10 (00001.110000)2
Person
(1.11)2
Data Representation Process using Computer
Real
World Mathematical ADT Data Type
Object Model

Height Binary
Arabic Number Binary Number System,
of a Number
System with implementation details
Person System

Height
of a (1.75m)10 (00001.110000)2 (001.110)2
Person
(1.11)2 (001.110)2
• Data Type is collection of a set of values and a set of
operations, with the representation and implementation
details of the set of values & operations.
• Following details are considered in Data Type:
• How many bits should be used to represent integer,
fractions & characters,
• Whether zero charge should represent bit 0 or otherwise,
• Whether N-S magnetization should represent bit 0 or
otherwise,
• Order in which a sequence of bytes should be stored in
memory, etc.
• Data Type gives a definite structure (at Hardware &
Compiler level) to the data.
• Data Types:
• Built-in/elementary/primitive data types.
• Ex. Integer, Floating-point, Char, Boolean, Void.
• They are provided by all programming languages.
• User-defined data types.
• Built using Elementary Data Types,
• Ex. arrays, pointers, strings, structures, union etc.
• What is Data Structure?

• It is the Logical or Mathematical Model of organizing a


collection of data, representing some real life object or
conceptual entity.
• A good data structure should accurately represent the
relationships that exit among the data of the real life
object or concept.
• Its structure should facilitate efficient processing of data
to obtain information in real time.
Built-in Data Types
• Character Data Type

• It consist of the set of symbols


• {0,1,2,3,4,5,6,7,8,9,A,B,C,D….X,Y,Z,a,b,c,…x,y,z,
,?,*,+,-,/….}
• The set includes numeric digits, alphabetic letters and
special characters.
• It consist of the set of operations {arithmetic, relational,
logical (Boolean),bitwise, etc}
• Physical representation/storage:

• 1. Extended Binary Coded Decimal Inter-change


Code (EBCDIC)
• Eight bits are used to represent a character
• So, 28=256 characters can be represented
• 2. American Standard Code for Information
Interchange (ASCII)
• Seven bits are used to represent a character
• So, 27=128 characters can be represented
• 3. Huffman Code
• Integer Data Type

• It consist of the set of values


{…,-(n+1),-n,…-2,-1,0,1,2,…n,(n+1),…}

• It consist of the set of operations {addition, subtraction,


multiplication, integer-division, bitwise operations,
negation, etc.}
• Physical representation/storage:

1. Integers can be stored in sign-and-magnitude form.

The most significant bit (MSB) is used for sign and rest are
for magnitude

Ex. (+7)10=(0111)2 i.e. (+)10=(0)2 and (7)10=(111)2

(-7)10=(1111)2 i.e. (-)10=(1)2 and (7)10=(111)2


• Drawbacks:

• Needs a different set of rules for arithmetic operations,


apart from the conventional rules for binary arithmetic
operations.

• Zero has two representation;


0 =0000 =(+000) and
0 =1000 =(-000)
2. Integers can be stored in One’s complement form.

Ex. (+7)10=(0111)2 i.e. (+)10=(0)2 and (7)10=(111)2

(-7)10=(1000)2 i.e. (-)10=(1)2 and (7)10=one’s complement of


(111)2= (000)2

Drawbacks:
• Zero has two representation;
• 0 =0000 =(+000) and 0 =1111 =(-111)
3. Integers can be stored in Two’s complement form

Ex. (+7)10=(0111)2 i.e. (+)10=(0)2 and (7)10=(111)2

(-7)10=(1001)2 i.e. (-)10=(1)2 and


(7)10=two’s complement of (111)2= (001)2
• Size of Integer Data Type

• unsigned int = 16 (or 32) bits; Range = 0 to (216-1).

• signed int or int = 16 (or 32) bits; Range = -(216−1 -1) to


(216−1 -1).

32−1 32−1
• long int = 32 bits; Range = -(2 -1) to (2 -1).

• long long int =64 bits; Range = -(264−1 -1) to (264−1 -1).
• Floating Point Data Type
• It consist of the set of fractional values
{...-3.0...-2.9999…-1.0...0.0…,0.99….2.0…3.0…}
• It consist of the set of operations {arithmetic, relational,
logical, etc.}
• Physical representation/storage:
• Floating-Point Number (FPN):
• Ex.
• - (2.5)10 = - (010.100)2 = - (1.010)2 x2(1)
Base Exponent

- (2.5)10 = - (010.100)2 = - (1.010)2x2(1)

Sign Mantissa/Significand
• -(2.5)10 = -(0010.1)2 = -(1.010)2x2(1)

• (FPN)= <Sign> <Significand> x Base (<Exponent field>)

(FPN)= <Sign> <Fractional Part of Significand> x 2 (<Exponent field> - <Bias>)


• <Sign> is the sign bit; zero for ‘+’ and one for ‘-’.
• <Fraction part of Significand> is the fractional part of a
normalized binary number.
• Ex. (110.1100)2 is not a normalized binary number.
• (1.1011)2 * 22 is a normalized binary number,
• bit 1 is never stored,
• only the fractional part =1011 is stored.
• (1.011)2 * 2-3 is the normalized number of
(0.001011)2
• ‘2’ is the base
• <Exponent field> represents the true exponent.
• It represents how the floating point should be shifted.
• In order to increase the range and to be able to represent
negative exponents without a sign bit, a <Bias> is added.
• Format for storing a floating point data type:

Sign Exponent Fraction

• Format for single precision (32 bits) floating point:

Sign (1 bit) Exponent (8 bits) Fraction (23 bits)

• Bias =127
• 8 bits are used to represent true exponent, then the
number of true exponents = 0 to (28-1) i.e.,0 to 255.

0 1 2... 126 127 128 … 254 255

Bias
• Bias (B) is used for encoding.
• True exponent (TE) is encoded using the bias (B) to
obtain a Biased exponent (BE).
• Ex.
• if TE = 0, then BE = TE + B = 0 + 127 = 127.
• if TE = 1, then BE = TE + B = 1 + 127 = 128.
• if TE = -1, then BE = TE + B = -1 + 127 = 126.
• if TE = 127, then BE = TE + B = 127 + 127 = 254.
• if TE = -126, then BE = TE + B = -126 + 127 = -1.
Encoded Biased Exponents

0 1 2.. 126 127 128 … 254 255


- -126 … -1 0 1 … 127 -

True Exponents

• Biased Exponent Encoding is a simple way to represent


Negative Exponents without using a Sign bit.
Encoded Biased Exponents

0 … 127 … 255
Binary
00000000 … 01111111 … 11111111 Representation

True Exponents

Used for
representing the Used for representing
Number Zero the Number Infinity
• True exponent (TE) is obtained by subtracting the Bias
(B) from the Biased exponent (BE).
• TE = BE – B.

• Ex.
• if BE = 127, then TE = BE - B = 127 - 127 = 0.
• if BE = 254, then TE = BE - B = 254 - 127 = 127.

• Ex.
• -(2.5)10 = -(0010.1)2 = -(1.010)2x2(1)

• = -(1.010)2x2(1+127)

• = -(1.010)2x2(128)
Sign (1 bit) Exponent (8 bits) Fraction (23 bits)
- 128 010

1 10000000 01000000000000000000000000
Single Precision Floating Point Representation
• Single precision floating point representation for
Number Zero:
• (0)10 = +(0)10 = -(0)10
• Representation for +(0)10

Sign (1 bit) Exponent (8 bits) Fraction (23 bits)


+ 0 0

0 00000000 00000000000000000000000000
• Representation for -(0)10

Sign (1 bit) Exponent (8 bits) Fraction (23 bits)


- 0 0

1 00000000 00000000000000000000000000
• Single precision floating point representation for
Number Infinity (∞):
• Representation for +(∞)10

Sign (1 bit) Exponent (8 bits) Fraction (23 bits)


+ 11111111 0

0 11111111 00000000000000000000000000
• Representation for -(∞)10

Sign (1 bit) Exponent (8 bits) Fraction (23 bits)


- 11111111 0

1 11111111 00000000000000000000000000
• Single precision floating point representation for Not a
Number (NaN):
• NaN = Non-Real numbers
= {+∞ − ∞; -∞ + ∞; ±∞% ±∞; ±0% ±0;
±∞x0}

Sign (1 bit) Exponent (8 bits) Fraction (23 bits)


± 11111111 Non-Zero

0/1 11111111 11110000000000000000000000


• Range of single precision (32bits) floating point:
• Maximum value:
• Sign = +
• Max. Exponent = 2127=1.7014118*10+38 = 1.7014118e+38
= 1.7014118E+38
• Max. Value that can be represented by the Fractional part
of Max. Significand = (11111111111111111111111)2 (23
one’s)
• So, Max. Significand = (1.11111111111111111111111)2 =
(1.99999988079071044922)10
• Therefore, Max. Float Value = Max. Significand * Max.
Exponent
• =(1.99999988079071044922)10 * 1.7014118E+38
• = 3.4E+38

• Minimum Value:
• Sign = -
• Min. Exponent = 2-126 = 1.1754944E-38
• Min. Value that can be represented by the Fractional part
of Min. Significand = (00000000000000000000000)2 (23
Zero’s)
• So, Min. Significand = (1. 00000000000000000000000)2
• = (1.0)10
• Therefore, Min. Float Value = (-)Min. Significand * Min.
Exponent
• =(1.0)10 * 1.1754944E-38 = 1.2E-38.

• Range = -1.2E-38 to 3.4E+38


• Format for double precision (64 bits) floating point:

Sign (1 bit) Exponent (11 bits) Fraction (52 bits)

• Bias =1023
• Boolean Data Type:
• Set of Values = {0,1}
• Set of Operations = {Logical operations, etc.}
• Size = 8 bits.

• Void Data Type:


• void is a datatype that denotes there is no datatype i.e.,
there is no set of values and operations.
• For functions, it means that a function can not take any
data as input and does not return any data as output.
• For pointers, it means that its is a generic place-holder and
can be made to store the address of any other data types.
Derived Data Types

• They are derived from the built-in data types


• Pointer:
• Set of Values = {memory addresses}
• Set of Operations = {address_of (&),
value_in_an_address (*), Pointer_assignment,
Pointer_conversion, pointer_arithmetic (+,-), logical }
• Ex.
• int *p1, *p2, *p3,a;
• P1++; P2--; p1=p1+12; p2=p2-3; a=p1-p2 are legal.
• P1+p2; p1*p2; p1+2.0…etc. are illegal.

• Size = 32 bits.
• Array:
• Set of Values = set of values of a single data type.
• Set of Operations = operation on index [i], etc.

• One Dimensional Arrays:


• int Roll_No[80];
• Two dimensional arrays:
• int A[10][20];
• Three dimensional Arrays:
• int A[10][20][20];
• Array storage:
X[1] X[2] X[i] X[14] X[15]

One Dimensional Array X[15]

Memory Storage
• Array storage:
Row i=0

Row i=1

Row i=2

Two Dimensional Array X[i][j]

Row i=0 Row i=1 Row i=2

Row Major Memory Storage


• Array storage:

Col Col
j=0 j=4

Two Dimensional Array X[i][j]

Col j=0 Col j=1 Col j=4

Column Major Memory Storage


• Structure:
• Real world objects or concepts are composite in nature,
.i.e., they are composed of many types of data.
• Ex.
Address = {House No, Street Name, Street No.}
Student = {Name, Roll No, Height, Percentage_Mark}

• Structure is a convenient way to represent such composite


objects or concepts.
• Structure is a collection/aggregate of related variables that
represents a real world object or a concept.
• Declaration of a structure:

struct student
{
char Name[20];
int Roll_No;
char Course[10];
float CGPA;
};

• Memory is not allocated till this point of time.


• Declaration of a structure variable:

struct student student_detail;

Memory is allocated at this point of time.

Set of values = set of values of the elements of the structure


Set of operations = set of operations that are valid on the
elements of the structure
• Declaration of a structure variable:

struct student
{
char Name[20];
int Roll_No;
char Course[10];
float CGPA;
}student_1, student_2;
• Accessing the elements of a structure variable:

• Dot (.) operator


Ex. student_1.Name = “John”;
student_1.Roll_No = 11254;
student_1.Course = “Data_Structure”;
student_1.CGPA = 7.5;

• Objects of same structure can be assigned to each other


student_1 = student_2;
• Arrays of structure:

• struct student stud[80];

stud[1].Name = “John”;
stud[1].Roll_No = 11254;
stud[1].Course = “Data_Structure”;
stud[1].CGPA = 7.5;
• Passing structures to a function:
• Passing the elements of a structure to a function
• Func1(student_1.Name);
• Func2(student_1.Roll_No);
• Passing the address of the elements of a structure to a
function
• Func1(student_1.Name);
• Func2(&student_1.Roll_No);
• Passing the whole structure to a function by value
• Func1(struct student s); //declaration
• Func1(student_1); //calling by value
• Passing the whole structure to a function by reference
struct student student_1; //object of a structure
struct student *p; //pointer to a structure

p = &student_1; //assigning the address of a pointer


• Accessing the elements of a structure using
pointers
p->Name = “John”;
p->Roll_No = 11254;
p->Course = “Data_Structure”;
p->CGPA = 7.5;
Func1(struct student *ptr); //declaration

p = &student_1;
Func1(p); //calling by reference
• Union:
• It is similar to structure, but it stores only one data
element at any particular time.
• Size of union = size of its largest element.
union student
{
char Name[20]; //size = 20 bytes
int Roll_No; //size = 1 byte
char Course[10]; //size = 10 bytes
float CGPA; //size = 4 bytes
}student_1;
• Enumeration:
• It is a set of name integer constants.
• Ex.
• enum day = {Sunday, Monday, Tuesday};
• = { 0, 1 , 2 }(integer constants)
• enum day weekday, holiday;
• weekday =Monday;
• holiday = Sunday;
• typedef:
• It is a used to give a new name to built-in and derived
data types.
• Giving new names increases readability and error
correction.
• Ex.
typedef int Roll_no;
Roll_no class_roll_no;
class_roll_no = 12;
• Ex.
typedef struct student;
student student1, student2;
student1.Name = “John”;
student1.Roll = 20;
Real World Object
Measurement

Analog Data
Analog to Digital Conversion

Digital Input Data

Data is Represented using


Data Structures

Computer Program
Computer Program

Digital Output Data


Digital to Analog Conversion

Analog Output Data


• Types of Data Structure
• 1. Built-in & Derived Data Structure
• 2. Linear & Non-linear DS
• 3. Static & Dynamic DS
• 4. Persistent & Ephemeral
• 5. Sequential & Direct Access
• 2. Linear & Non-linear DS
• In linear DS, every data element has a unique successor
and a predecessor.
• Ex. Array, linked list.
• In non-linear DS, every data element may have more than
one predecessor as well as successor.
• Ex. Trees, graphs.
• 3. Static & Dynamic DS
• If a Data Structure is created before executing a program,
then it is called a static DS.
• Ex. Array
• If a Data Structure is created at run-time, then it is called a
dynamic DS.
• Ex. Linked list, trees, graphs implemented using dynamic
memory management and pointers.
• 4. Persistent & Ephemeral DS
• Operations processing a data may modify it.
• If the data is modified by a process, there are two versions
of a data
• i). The modified/updated version of the data
• ii). The unmodified/previous version of the data,
which are saved before any modification is done.
• A Data Structure that supports operations on the updated
and previous version of data is called persistent DS.
• A Data Structure that supports operations only on the
updated version of data is called ephemeral DS.
• 5. Sequential & Direct Access DS
• Sequential access means that to access nth element, one
must access the preceding (n-1) data elements.
• Ex. Linked list.
• Direct access means that one can directly access nth
element without accessing the preceding (n-1) data
elements.
• Ex. Array
• Algorithm:
• It is a finite ordered set of unambiguous and effective
steps which when followed, accomplish a particular task
by accepting zero or more inputs and generates at least
one output and terminates.

Algorithms + Data Structures = Programs


Algorithms + Data Structures = Programs
• Good Algorithms and good data structure are needed
to have good programs
• A good algorithm is measured by two parameters
• i). Time complexity
• ii). Space complexity
• i). Time complexity
• It is the amount of time taken by the algorithm to execute
its instructions.
• It is very difficult to compute the exact time taken by an
algorithm.
• It is machine dependent.
• Time is measured by counting the number of operations
(key operations) in an algorithm.
• Ex. Time Taken
int main ( )
1 unit
{ int A[5]={9,2,8,3,1};
1 unit
int i;
for (i=0;i<5;i++) 1*(5+1) unit
printf(“i=%d\n”,A[i]); 1*5 unit
return; 1 unit
}

Therefore, total time taken by the algo. = 1+1+6+5+1=14


units of time.
• Ex. Time Taken
int main ( )
1 unit
{ int n=1000;
1 unit
int i;
for (i=1;i<=n;i++) 1*(n+1) unit
printf(“i=%d\n”,i); 1*n unit
return; 1 unit
}
Therefore, total time taken by the algo.
= 1+1+(1*(n+1))+(1*n)+1 = 2n + 4
• Ex. Time Taken
int main ( )
1 unit
{ int n=1000;
int i,j; 1 unit

for (i=1;i<=n;i++) 1*(n+1) unit


{for (j=1;j<=n;j++) 1*(n+1)*n unit
printf(“i=%d\n”,i); 1*n*n unit
}
return; 1 unit
}
Total time = 1+1+(n+1)+(n+1)*n+ (n*n)+1
= 2n2+2n+4
Total time = 2n2+2n+4
i.e., f(n) = 2n2+2n+4
where ‘n’ is size of the input
• So, time taken by an algorithm can be expressed using a
polynomial function of ‘n’.
• Algorithms with polynomial time complexity are written
as nc, where ‘c’ is some constant. Ex. n10, n3, n2.
• Algorithms with nlog2(n) time complexity are considered
to have superlinear time complexity.
• Polynomial functions do not grow very rapidly if the
value of constant ‘c’ is small.
• Algorithms with polynomial time complexity are able to
solve reasonable-sized problems, if the value of constant
‘c’ is small.

• Exponential functions involve ‘n’ as an exponent.


• Ex. 2n, nn and n!≅(n/2.56)n.
• Exponential functions grow very rapidly.
• Algorithms that have exponential time complexity are
good for solving small sized problems & are very slow for
solving large sized problems.
• Linear functions are polynomial functions with order 1.
• Ex. f(n) = 2n+4
• Linear functions grows proportionately with the size of
the problem.
• Sub-linear functions are polynomial functions such that
0≤ f(n) ≤ c.n where c is some positive constant.
• Ex. f(n) = log2(n)
• Sub-linear functions grows very slowly with the size of
the problem.
• Algorithms with linear and sub-linear functions time
complexity are required to solve very large sized problem.
• Constant functions have constant value for any n.
• Ex. f(n) = 1
• Algorithms with constant time complexity are most
desirable.
Exponential
Time taken= f(n)

Constant

Problem size =n

Growth of Some Standard Functions


• Some notations to represent the time complexity of
algorithms:
• i). Big O notation denoted as O.
• ii). Little o notation denoted as o.
• iii). Omega notation denoted as Ω.
• iv). Little Omega notation denoted as ω.
• v). Theta notation denoted as Ɵ.
• These notations are called Asymptotic notations
• i). Big O notation.
• Let f(n) & g(n) be functions defined on positive integers.
• Then, O(g(n)) = {f(n)}
Such that 0 ≤ f(n) ≤ cg(n)
where c & n0 are positive constants & for all n ≥ n0
• So, f(n) is upper bounded by g(n) for some c & n0.
• f(n) = O(g(n)) implies that f(n) is a member of the set
O(g(n)) and is upper bounded by cg(n).
• f(n) = O(g(n)) <=> f(n) ∈ O(g(n))
Big O Notation Limit Definition
f(n) = O(g(n)) 𝒇(𝒏)
lim 𝝐[ 𝑜, ∞)
𝒏→∞ 𝒈(𝒏)

Including Excluding
Time taken= f(n)

Problem size =n
• Big O is used to represent the maximum time taken by an
algorithm to solve a computational problem.

• i.e., it represents worst case time complexity of an


algorithm.

• Worst case time complexity is always the concern for an


algorithm designer.
• Ex. Let f(n) = 5n+2 and g(n) = n.

• For f(n) = O(g(n)) to be true, f(n) ≤ cg(n) must hold for +ve
c and n0.
• => f(n) ≤ cg(n).
• => 5n+2 ≤ cn…..eqn.-1.
• => when n=1, then we have 7 ≤ c => c = 7.
• => when n <1, then LHS>RHS, so n0 = 1.
• => so, for c = 7 and n0 =1, the above equation is true

• => Therefore, f(n) = O(g(n)) for c = 7 and n0 =1

• =>i.e., f(n) = O(n) for c = 7 and n0 =1


𝒇(𝒏)
𝒇 𝒏 = 𝑶 𝒈(𝒏) => lim 𝝐[ 𝑜, ∞)
𝒏→∞ 𝒈(𝒏)

𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim = 𝟓 𝝐 [0, ∞)
𝒏→∞ 𝒈(𝒏) 𝒏→∞ 𝒏

Therefore, f(n) = O(g(n))


f(n) = O(n).
• Ex. Let f(n) = 5n+2 and g(n) = n2.

• For f(n) = O(g(n)) to be true, f(n) ≤ cg(n) must hold for +ve
c and n0.
• => f(n) ≤ cg(n).
• => 5n+2 ≤ cn2 ...eqn.-2.
• => when n=1, then we have 7 ≤ c. => c = 7.
• => for n =1, then LHS ≤ RHS, so n0 = 1.
• *Note: there could be any other values for c and n0.
• => so, for c = 7 and n0 =1, the above equation is true
• => Therefore, f(n) = O(g(n)) for c = 7 and n0 =1

• =>i.e., f(n) = O(n2) for c = 7 and n0 =1

𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim 𝟐
= 0 𝝐 [0, ∞)
𝒏→∞ 𝒈(𝒏) 𝒏→∞ 𝒏
• Likewise, f(n) = O(n3), f(n) = O(n4) are true for some c & n0.

• So f(n) is upper bounded by O(n), O(n2), O(n3) & O(n4).


c3g(n3)
c2g(n2)
Time taken= f(n)

c1g(n)

f(n)

n0
Problem size = n
• Big O notation does not specify the nature of upper bound.

• It just gives the upper bound.


• ii). Little o notation:
• It is used to denote the set of functions that act as loose
upper bound for f(n).

• Let f(n) & g(n) be functions defined on positive integers.


• Then, o(g(n)) = {f(n)}
Such that 0 ≤ f(n) < cg(n)
where c & n0 are positive constants for all n ≥ n0

• So, f(n) is loosely upper bounded by g(n) for some c & n0


Little o Notation Limit Definition
f(n) = o(g(n)) 𝒇(𝒏)
lim =𝟎
𝒏→∞ 𝒈(𝒏)
• Ex. Let f(n) = 5n+2 and g(n) = n2.

• It is very clear that (5n+2) < n2.


• Therefore, f(n) = o(n2),

𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim 𝟐
=0
𝒏→∞ 𝒈(𝒏) 𝒏→∞ 𝒏

• Further, f(n) = o(n2), f(n) = o(n3), f(n) = o(n4) are also true
c2g(n3)
Time taken= f(n)
c1g(n2)
Loose Upper Bounds

f(n)

n0 n 0
Problem size = n
• iii). Omega notation denoted as Ω:
• It is used to denote the set of functions that act as lower
bound for f(n).
• Let f(n) & g(n) be functions defined on positive integers.

• Then, Ω(g(n)) = {f(n)}


Such that 0 ≤ cg(n) ≤ f(n)
where c & n0 are positive constants for all n ≥ n0

• So, f(n) is lower bounded by g(n) for some c & n0


Ω Notation Limit Definition
f(n) = Ω(g(n)) 𝒇(𝒏)
lim = (0, ∞]
𝒏→∞ 𝒈(𝒏)

Excluding Including
Problem size =n
• f(n) = Ω(g(n)) implies that f(n) is a member of the set
Ω(g(n)) and is lower bounded by cg(n).
• Omega Ω is used to represent the minimum time taken by
an algorithm to solve a computational problem.

• i.e., it represents best case time complexity of an algorithm.

• Best case time complexity is not the concern for an


algorithm designer.
• Ex. Let f(n) = 5n+2 and g(n) = n.

• For f(n) = Ω(g(n)) to be true, cg(n) ≤ f(n) must hold for +ve
c and n0.
• => cg(n) ≤ f(n).

• => cn ≤ 5n+2
• => when c=5, then LHS < RHS for all +ve n0
• => f(n) = Ω(g(n))
• => f(n) = Ω(n)
𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim = 𝟓 𝝐 (0, ∞]
𝒏→∞ 𝒈(𝒏) 𝒏→∞ 𝒏

• Therefore, f(n) = Ω(n)


f(n)
Time taken= f(n)

c1g(n)

c2g(n)

n0 n0
Problem size = n
• Omega Ω notation does not specify the nature of lower
bound.

• It just gives the lower bound.


• iv). Little Omega notation denoted as ω:
• It is used to denote the set of functions that act as loose
lower bound for f(n).

• Let f(n) & g(n) be functions defined on positive integers.


• Then, ω(g(n)) = {f(n)}
Such that 0 ≤ cg(n) < f(n)
where c & n0 are positive constants for all n ≥ n0

• So, f(n) is loosely lower bounded by g(n) for some c & n0


ω Notation Limit Definition
f(n) = ω(g(n)) 𝒇(𝒏)
lim =∞
𝒏→∞ 𝒈(𝒏)
• Ex. Let f(n) = 5n2+2 and g(n) = n.
• Clearly, n < (5n2+2).

• Therefore, f(n) = ω(g(n)),


• f(n) = ω(n),
𝟐
𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim =∞+0=∞
𝒏→∞ 𝒈(𝒏) 𝒏→∞ 𝒏
• Therefore, f(n) = ω(n)
• Ex. Let f(n) = 5n+2 and g(n) = log2(n).
• Clearly, log2(n) < (5n+2).

• Therefore, f(n) = ω(g(n)),


• f(n) = ω(log2(n)),
𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim
𝒏→∞ 𝒈(𝒏) 𝒏→∞ log 𝟐 𝒏

• Since, the above is in an indeterminate form, use


L’Hospital’s Rule.
𝟓𝒏 + 𝟐 5
lim = lim =∞
𝒏→∞ log 𝟐 𝒏 1Τ𝑛
𝒏→∞
• Therefore, f(n) = ω(g(n)),
• f(n) = ω(log2(n)),
f(n)
Time taken= f(n)

n0
Problem size =n
• v). Theta notation denoted as Ɵ:
• It is used to denote the set of functions are between a tight
upper and a tight lower bound for f(n).
• Let f(n) & g(n) be functions defined on positive integers.

• Then, Ɵ(g(n)) = {f(n)}


Such that 0 ≤ c1g(n) ≤ f(n) ≤ c2g(n)
where c1, c2 & n0 are positive constants for all n ≥ n0
• So, f(n) is tightly lower bounded by g(n) for some c1 & n0
and is tightly upper bounded by g(n) for some c2 & n0
Ɵ Notation Limit Definition
f(n) = Ɵ(g(n)) 𝒇(𝒏)
lim = (0, ∞)
𝒏→∞ 𝒈(𝒏)

Excluding Excluding
Time taken= f(n)

Problem size =n
• f(n) = Ɵ(g(n)) implies that f(n) is a member of the set
Ɵ(g(n)) and is sandwiched between c1g(n) & c2g(n).

• Theta Ɵ is used to represent the average time taken by an


algorithm to solve a computational problem.
• i.e., it represents average case time complexity of an
algorithm.
• For most cases, average time complexity is equal to worst
case time complexity.
• It is also of concern for an algorithm designer.
• Ex. Let f(n) = 5n+2 and g(n) = n.

• For f(n) = Ɵ(g(n)) to be true, c1g(n) ≤ f(n) ≤ c2g(n) must


hold for +ve c1, c2 and n0.
• => c1g(n) ≤ (5n+2) ≤ c2g(n).

• => c1n ≤ 5n+2


• => when c1=5, then LHS < RHS for all +ve n0
• => 5n+2 ≤ c2n
• => when c2=7, then LHS < RHS for all +ve n0 ≥1
• Therefore, c1g(n) ≤ (5n+2) ≤ c2g(n) for c1=5 & c2=7.
• => f(n) = Ɵ(g(n))
• => f(n) = Ɵ(n)

𝒇(𝒏) 𝟓𝒏 + 𝟐
lim = lim = 𝟓 𝝐 (0, ∞)
𝒏→∞ 𝒈(𝒏) 𝒏→∞ 𝒏

• Therefore, f(n) = Ɵ(n)


• Space Complexity:
• It is the amount of memory used by an algorithm (including
the input values) to execute and produce the result.
• While executing, algorithm uses memory space for three
reasons:
1. Instruction Space
It's the amount of memory used to save the compiled
version of instructions.
2.Environmental Stack
Amount of memory required for saving the state of variables
during function calls.
3.Data Space
Amount of memory required for storing variables and
constants.
• For calculating the Space Complexity of any algorithm,
usually only Data Space is considered and Instruction
Space and Environmental Stack are neglected.
Array
• Ex.
Array Size
function(A,n)
{
int i; 1 unit of extra memory
for (i=0;i<n;i++)
A[i]=0;
}

Space Complexity, s(n) = 1


i.e., s(n) = O(1)
• Ex.
function(A,n)
{ 2 units of extra memory
int i, j;
int B[n][n]; n*n units of extra memory
for (i=0;i<n;i++)
for (j=0;j<n;j++)
B[i][j]=0;
}
Space Complexity, s(n) = 2+(n*n) = 2+n2
i.e., s(n) = O(n2)
• Ex. Recursive function

Sequence of function Call


n+1. func1(0)
void func1(int n)
{ n. func1(1)

if(n>=1) n-1. func1(2)


func1(n-1);
printf("value= %d",n); 2. func1(n-1)
return; 1. func1(n)
}
Memory Space
• Ex. Recursive function

Sequence of function Call


void func1(int n=3)
{ 4. func1(0)
if(n>=1)
3. func1(1)
func1(n-1);
printf("value= %d",n); 2. func1(2)
return; 1. func1(3)
}
Memory Space
• Ex. Recursive function

Sequence of function Call


void func1(int n=3)
{ 4. func1(0) Value=0
if(n>=1)
3. func1(1) Value=1
func1(n-1);
printf("value= %d",n); 2. func1(2) Value=2
return; 1. func1(3) Value=3
}
Output: 0,1,2,3 Memory Space
Space Complexity, s(n) = n+1
i.e., s(n) = O(n)
• Ex. Recursive function
4. func1(0)
void func1(int n=3)

Sequence of function Call


{ Value=1
if(n>=1) 3. func1(1)
printf("value= %d",n); Value=2
func1(n-1);
2. func1(2)
return;
} Value=3
1. func1(3)
Output: 3,2,1
Space Complexity, s(n) = n-1
i.e., s(n) = O(n)
• Space complexity is also expressed using Asymptotic
notations.

• ***Reading Assignment: Space complexity.


List Data Structure
• List Data Structure is a homogeneous collection of
elements.
• Ex. List of students from Odisha.
• List of Top Engineering Institutes in India.
• List of Top five Cricket teams in the world.

• Its elements may be order or unordered.


• Set of Operation for List Data Structure are:
• 1. Creating a list
• 2. Inserting data elements into list
• 3. Deleting data elements into list
• 4. Searching the list for a specific data element
• List Data Structure can be implemented using:
1. Array
2. Linked list
1. Array implementation of List Data Structure

i). Static Creation of List using Array:

float marks_list_DSA[20]; //creating a list


ii). Dynamic Creation of List using Array:

float *marks_list_DSA; //static declaration of list

//dynamic creation of list


marks_list_DSA= (float *) malloc(20*sizeof(float));

• malloc is a library function to allocate memory space of


some specified size and it returns the address of the first
memory location.
• Insertion operation in List:
[0] [1] [6]

78.0 69.0 59.0 55.0 marks_list_DSA [15]

88.0 78.0 69.0 59.0 55.0

• Worst case time complexity for Insertion, T(n) = O(n)


• Deletion operation:
Deletion at the first location requires shifting all
the elements of the array i.e., T(n)=O(n).

• Searching operation:
i). Search Time for an element, T(n) = O(log(n)), when the
list is sorted. It is called binary search.
ii). Search Time for an element, T(n) = O(n) when the
list is not sorted.
• Limitation of Array implementation of List Data
Structure:
i). Size of the list has to be known in advance. This not
practical in many situations

ii). Operations are costly, O(n).

Array implementation of List is avoided in many cases.


2. Linked list implementation of List Data Structure
• In a linked list, a data element is stored using node.
• A linked list is a collection of nodes.

Data Element Address of Next Node

Graphical Representation of a Node


Data Element

Graphical Representation of a Node


Header

87.0 77.0 45.0 65.0 X

Graphical Representation of a Linked List of mark list

• Header Pointer is used to store the address of the first


node of the Singly Linked List.
Header

DSA
Marks 87.0 77.0 45.0 65.0 X

Header Node
• Header Node contains information about the Singly
Linked List.
87.0 568 87.0 212 87.0 002 87.0 0
Address of Address of Address of Address of
node-1: node-2: node-3: node-4:
100 568 212 002

100
Address of Header:
999
Internal representation of a linked list
Declaration of a Node in C language:
struct node
{
float Data;
struct node *next;
};

Data next

Graphical Representation of Node


Declaration of a Node in C language:
typedef struct nodeType
{
float Data;
struct nodeType *next;
} node;

node *header; // node becomes a data type


Data next
Graphical Representation of Node
Note on Pointer:
int A=11 int *B int **C
Address of A: Address of B: Address of C:
999 777 555
B = &A; => B = 999
C = &B; => C = 777
Address of A=B; => Address of A=999
Value of A=*B; => Value of A = *999 = 11
Note on Pointer:
int A=11 int *B int **C
Address of A: Address of B: Address of C:
999 777 555
B = &A; => B = 999
C = &B; => C = 777
Address of B = C; => Address of B = 777

Address of A= *C; => Address of A= *777 = 999


Note on Pointer:
int A=11 int *B int **C
Address of A: Address of B: Address of C:
999 777 555
B = &A; => B = 999
C = &B; => C = 777

Value of A= **C; => Value of A= **777 = *999 = 11


Note on Pointer:

int A=11 int *B int **C


B = &A; C = &B;
• 1. Creating an empty linked list:
Header
Address of Header:
1000

/*create Header*/
node *Header;
// Header will have junk value
• 1. Creating an empty linked list:

Empty Linked List


Header = NULL
Address of Header:
1000

Header = NULL;
• 1. Creating an empty linked list using a function:

//function to create an empty list


void CreateEmptyList (1000)
{
*1000 = NULL;
}
• Creating an empty linked list:

/*function to create an empty list*/


void CreateEmptyList (node **header)
{
*header = NULL; //NULL is a macro defined in stdio.h
}
Address of Header:
1000
Header=NULL
Header=9999
ptr->data = 65;
ptr->next = NULL;
If (*Header = = NULL) Then
Create aanew 65 X
node, space for a new node
//Create memory
Ptr=999
Ptr Fill dataptr in new node,
Address of*)New
= (node malloc (sizeof(node));
Node:
//Assign
Make the Address
its value of the
of next new node to Header
as NULL
9999
Header = ptr; => Header =999
2. Inserting an element into an Empty Linked List
• 2. Inserting elements in an empty linked list:

void InsertingInEmptyList(node **header, int data)


{ node *ptr;
if(*header = = NULL) //check if the list is empty
{ printf("\nThe List is Empty");
//Create a memory space for a new node
ptr = (node *) malloc (sizeof(node));
ptr->data = data;
ptr->next = NULL;
• 2. Inserting elements in an empty linked list:

//Make the header to point to the new node


*header = ptr;
printf("\nData inserted Successfully!!!");
}
else
printf("\nThe List is not Empty");
return;
}
Address of Header: If (ptr->next = = NULL)
If (ptr->next! = = NULL)
1000 Then Create a new node &
Then
Header=9999 assign its address to the last
ptr=ptr->next.
Ptr node.

8 7 5
65 24 39 X 80 X
8 7 5
Add of Add of Add of Add of
Node-1: Node-2: Node-3: New Node:
9999 88 77 55
3. Inserting an element into an Non-Empty Linked List
• 3. Inserting elements into an non-empty linked list:

void InsertingInListEnd(node *header, int data)


{ node *ptr1,*ptr2;
ptr1 = header;
//move to the last node of the list
while(ptr1->next! = NULL)
{ptr1 = ptr1->next;}
• 3. Inserting elements into an non-empty linked list:
//create a new node to insert
ptr2 = (node *) malloc (sizeof(node));
ptr2->data = data;
ptr2->next = NULL;
//insert the new node at the end of the list
ptr1->next = ptr2;
}
Header

1 8 7 5
22 0 65 24 39 80 X
8 7 5

New Node 10

• 4. Inserting an elements at the Beginning of a linked


list:
Header Create a New Node at Address 10
If 22 5
ptr->data != 39
Ptr Then 5ptr = ptr->next.

8 7 15
65 24 39 80 X
8 7 05

5. Inserting an elements at Specific location (after 39) of a


linked list:
Address of Header: if((*header)->next = = NULL)
1000 {
Header=9999
Header=NULL ptr1 = *header;
*header = NULL;
free(ptr1);
}
65 X
Add of Ptr
Node-1:
9999
6. Deleting an element at the End of Linked List
Address of Header:
1000 Ptr1
Header
Ptr2

8
65 80 X
8

Ptr2 = *header;
Ptr1 = (*header)->next;
6. Deleting an element at the End of Linked List
Header Free the space
Ptr2 Ptr1 for the deleted
Node

8 7 5
65 24 39 X 80 X
8 7 5
while(ptr1->next != NULL)
{ ptr2 = ptr1;
ptr1 = ptr1->next;}
6. Deleting an element at the End of Linked List
• 6. Deleting an elements from the end of a linked list:
void DeleteInListEnd(node **header, int data)
{ node *ptr1,*ptr2;
//when there is only one node in the list
if((*header)->next==(node *)NULL)
{
ptr1=*header;
*header=NULL;
free(ptr1);
}
• 6. Deleting an elements from the end of a linked list:
//when there is more than one node in the list
else
{ ptr2 = *header;
ptr1= (*header)->next;
while(ptr1->next != NULL)
{ ptr2 = ptr1;
ptr1 = ptr1->next;}
ptr2->next = NULL;
free(ptr1);
}}
Header

8 7 5
65 X 24 39 80 X
8 7 5

Ptr1

7. Deleting an elements at the Beginning of a linked list:


Header if(ptr1->data!=39)
Ptr2
{ptr2-next= ptr1;
Ptr1 ptr1 = ptr1->next;}

8 75 80 X
65 24
8 75
5
39
5
• 8. Deleting an elements at Specific location (at 39) of a
linked list:
if(Header!=NULL)
Header Ptr {ptr=Header;
Header=ptr->next;
Free(ptr);
Ptr=Header;}

8 7 5
65 24 39 80 X X
8 7 5

• 9. Deleting an Entire Linked List:


• Traversing a Linked List:
Header=9999 if(ptr->next!=NULL)
Ptr {ptr = ptr->next;}

8 7 5
65 24 39 80 X
8 7 5

10. Traversing a Linked List


• 10. Traversing a Linked List

void ListTraverse(node *header)


{ while(header!=NULL)
{ printf("\n%d ",header->data);
header=header->next;}
}
return;
}
Header Ptr3 Ptr2 Ptr1
X

8 7 5 3
65 X 24 39 46 80 X X
8 7 5 3
Ptr2=Header; if(ptr1!=NULL)
Ptr1=Ptr2->next; if(ptr1==NULL)
{ptr3=ptr2;
Ptr3=NULL; {Header=ptr2;}
Ptr2=ptr1;
Ptr2->next=NULL; Ptr1=ptr1->next;
• Reversing a linked list: Ptr2->next=ptr3;}
Circular Linked List
• One of the limitations of a Singly Linked List is that one
can not access the previous elements of the list.
Header

8 7 5 3 1
65 24 39 46 80
8 7 5 3 1

• Last node has the address of the first node


• A node can be reached from any other node
Circular Linked List
Header
8 7 5 3 1
65 24 39 46 80
8 7 5 3 1

• Last and first node can be easily accessed from the


header.
Circular Linked List
Header X data data data X

• Makes two way traversal possible in a linked list at the


cost of extra pointers.

Doubly Linked List


Declaration of a Node:
struct node
{
struct node *prev;
float data;
struct node *next;
};

prev Data next

Graphical Representation of Node


Declaration of a Node:
typedef struct nodeType
{
struct node *prev;
float data;
struct node *next;
} node;
node *header;
prev Data next

Graphical Representation of Node


Header Ptr

X data data data X data X

Inserting an element at the end of Doubly Linked List


Header Ptr
1
50
1

X 20 40 60 X

new->next = ptr->next;
(ptr->next)->prev = new;
ptr->next = new;
new->prev = ptr;
Inserting an element at Specific location (after 40) of
Doubly Linked List
Other operations on Doubly linked List:
• CreateDLL( ).
• Insert Element at Beginning of DLL ( ).
• Traverse a DLL ( ).
• Delete at the End of DLL( ).
• Delete at Start of DLL( ).
• Delete at Specific Location of DLL( ).
• Delete the Entire DLL( ).
• Search for an element in DLL( ).
Header data data data

Doubly Circular Linked List


Operations on Doubly Circular linked List:
• Create DCLL( ).
• Insert Element.
• Traverse.
• Delete Element.
• Search for an element.

**Very efficient for Search Operation


Applications of Linked List:
• Used to implement other data structures like stacks,
queues, trees & graphs.
• Polynomial representation &
manipulation.(**Home Work).
• Sparse matrices representation.
• Maintain a directory of names.
• Memory management.
Stack Data Structure:
• Stack is a list in which the data element that has been
inserted first is the last one to be deleted from the list
and the data element that has been inserted last is the
first one to be deleted from the list.

STACK 18 Last Data Element

55 Second Data Element

74 First Data Element


• Push Operation:
• It is the operation to insert data element into a stack using
a pointer variable called top.

STACK 18 Top

55 Top
74 Top
• Pop Operation:
• It is the operation to delete data element from the top of
the stack using a pointer variable called top.

STACK 18 Top

55 Top
74 Top
• Push and Pop Operation takes place only at one end of
the Stack which is pointed by the top pointer variable.
• Other Operations are:
• CreateEmptyStack( ),
• IsStackEmpty( ),
• GetTopofStack( ),
• IsStackFull( ),
• 1. CreateEmptyStack( ):
• This function Creates an Empty Stack.

STACK

Top
• 2. IsStackEmpty( ):
• This function checks if an Stack is Empty.

STACK

Top
• 3. GetTopofStack( ):
• This function gives the data element pointed by the
pointer variable top.

STACK 18 Top

55
74
• 4. IsStackFull( ):
• This function checks if an Stack is full or not.

Top
STACK 18
55
74
Stack Implementation
• 1. Array Implementation
• 2. Linked List Implementation
1. Array Implementation of Stack
Data Structure
1. 1. CreateEmptyStack( )

Top = -1;
STACK

[0] [1] [maxsize-1]

Top= -1 indicates that Stack is


Empty.
maxsize = maximum size of Stack
1. 1. CreateEmptyStack( )
int main( )
{ int Top;
int *array; //array is the Array whose size is dynamically specified
int maxsize = 3;
CreateEmptyStack(&Top, &array, maxsize);
return 0;
}
1. 1. CreateEmptyStack( )
void CreateEmptyStack(int *Top, int **array, int maxsize)
{
//Assign Top = -1 to indicate that stack is empty
*Top = -1;
//Dynamic creation of array of size = maxsize
*array = (int *)malloc(sizeof(int)*(maxsize));
}
1. 2. Push( ) Top = 0;

Top = -1;
STACK

[0] [1] [maxsize-1]

22

22 Top = Top+1; =>Top= -1+1=0

Array[Top] = 22; => Array[Top] = 22


STACK 1. 2. Push( ) Top = 2;

44 [0] [1] [2] [maxsize-1]

22 33 44
33
22 Top = Top+1;
Array[Top];
1. 2. Push( )

void Push(int *Top, int array[ ], int data)


{
*Top = *Top+1;
array[*Top] = data;
}
STACK 1. 3. Pop( ) Top = 2;
Top = 1;

44 [0] [1] [2] [maxsize-1]

22 33 44
33
22 Top = Top-1;=>Top = 2-1 = 1
1. 3. Pop( )

void Pop(int *Top)


{
*Top = *Top -1;
}
STACK 1. 4. GetTopofStack( ) Top = 2;

44 [0] [1] [2] [maxsize-1]

22 33 44
33
22 Top_Data = Array[Top];
1. 4. GetTopofStack( )
int GetTopofStack(int *Top, int head[ ])
{
int data;
data = head[*Top];
return (data);
}
1. 5. IsStackFull( )
int IsStackFull(int *Top, int maxsize)
{
int true =1, false = 0;
if(*Top = = (maxsize-1))
return(true);
else
return(false);
}
1. 5. IsStackEmpty( )
int IsStackEmpty(int *Top)
{
int true =1, false = 0;
if(*Top = = -1)
return(true);
else
return(false);
}
2. Linked List Implementation of
Stack Data Structure
Top
STACK

Node-1
44 Node-3 Node-2
44 33 22 X

33
22
STACK 2. 1. CreateEmptyStack( )

Top = NULL
2. 1. CreateEmptyStack( )

void CreateEmptyStack(node **Top)


{
*Top=NULL;
}
STACK 2. 2. Push( ) Top
Top = NULL

Node-1
22 X

22
STACK 2. 2. Push( ) Top

Node-1
44 Node-3 Node-2
44 33 22 X

33
22
2. 2. Push( )
void Push(node **Top, int data)
{
node *ptr;
//Create a new node
ptr=(node *)malloc(sizeof(node));
ptr->data=data;
ptr->next=*Top;
*Top=ptr;
}
STACK 2. 3. Pop( ) Top

Node-1
44 Node-3 Node-2
44 33 22 X

33
22
Ptr
2. 3. Pop( )

void Pop(node **Top)


{
node *ptr;
ptr = *Top;
*Top = (*Top)->next;
free(ptr);
}
2. 4. GetTopofStack( )
int GetTopofStack(int **Top)
{
int data;
data = (*Top)->data;
return (data);
}
2. 5. IsStackEmpty( )
int IsStackEmpty(int **Top)
{
int true =1, false = 0;
if(*Top = = NULL)
return(true);
else
return(false);
}
Applications of Stack Data Structure
Applications of Stack

1. Parentheses Checker
2. Conversion of infix expression to postfix expression
3. Evaluation of postfix expression
4. Conversion of infix expression to prefix expression
5. Evaluation of prefix expression
6. Recursion
1. Parentheses Checker
• Parentheses are used in Programming Languages and
Mathematical Expression.
• Ex. {{( )}}, (((a-b)+2)+(c-d))*e/3.
• In a valid expression, there are equal number of left &
right parentheses.
• Every right parentheses is preceded by its
corresponding left parentheses.
• Example of Valid Expression:
• (((( )))), {{( )}}, {{( )[ ]( ) }{ }}
• Example of Invalid Expression:
• (((( ))), {{( )}, {{( ) [ ( ] }{ })
1. Parentheses Checker
• Ex. { a*(b-c) }
STACK

• If the Stack is Empty by the


End of the Expression,
• Then the Expression is Valid
1. Parentheses Checker
• Ex. { a*(b-c}
STACK

• If the Stack is Not Empty by


the End of the Expression,
• Then the Expression is Invalid
Parentheses Checker Algorithm:
1. Scan the Expression, character by character, from left to right until the
end.
2. {If the character is an Operand, Then ignore it.
3. If the character is an Operator, Then ignore it.
4. If the character is a Left Parentheses, Then Push it into the Stack.
5. If the character is a Right Parentheses,
6. Then, Check-If the Parentheses in the Top of Stack is its Corresponding
Left Parentheses
7. If -Yes, Then Pop the Left Parentheses and do not Push the Right
Parentheses.
8. If the Stack is Empty, when all the characters of an expression are
scanned, Then, the Expression is Valid.
9. If the Stack is Not-Empty, when all the characters of an expression are
scanned, Then the expression in Not Valid.}
2. Infix Expression to Postfix Expression Conversion

• In Infix Expressions, an operator is placed in between two


operands.
• Ex. A + B
• A-B
• A*B
• (A+B)/C
• ((A+B)*C)/D-E
2. Infix Expression to Postfix Expression Conversion
Precedence Operator Group Associativity
Highest=16 ()[] Left Right
14 * / % Left Right
13 + - Left Right
2. Infix Expression to Postfix Expression Conversion
Precedence Operator Group Associativity
Highest=16 ()[] Left Right

13 + - Left Right

• Ex.
• 5+1-3+4-1 = ((((5+1)-3)+4)-1) = (((6-3)+4)-1) = ((3+4)-1)
= (7-1) = 6
2. Infix Expression to Postfix Expression Conversion
Precedence Operator Group Associativity
Highest=16 ()[] Left Right
14 * / % Left Right

• Ex.
• 5*3/2 = ((5*3)/2) = (15/2) = 7.5
• 5/3*2 = ((5/3)*2) = (1.666*2) = 3.332
2. Infix Expression to Postfix Expression Conversion
Precedence Operator Group Associativity
Highest=16 ()[] Left Right

• Ex.
• 5-3*2/2 = (5-((3*2)/2)) = (5-(6/2)) = (5-3) = 2
• 5-2+4/2 = (5-2+(4/2)) = (5-2 + 2) = (3+2) = 5
2. Infix Expression to Postfix Expression Conversion
• Ex. • Ex.
• ((5-2)+6)/((3-2)*4) • 7*4/(6-4)-4
• => (3+6)/((3-2)*4) • =>7*4/2-4
• => 9/((3-2)*4) • =>28/2-4
• => 9/(1*4) = 9/4 = 2.25 • =>14-4 =10
• Parentheses can be used to alter precedence of operators
• This makes the evaluation algorithms of such expressions
difficult.
• So, infix expressions are converted into post or prefix
expressions for ease of evaluation.
2. Infix Expression to Postfix Expression Conversion
• In Postfix Expression, an operator is placed after its two
operands.
• Ex.
• Ex.
• A + B - C => A + B - C
• A+B => AB+
• => AB+ - C => AB+ - C
• B+A => BA+
• => AB+C-
• A-B => AB-
• B-A => BA- • Ex.
• A/B => AB/ • A * B / C => A * B / C
• A*B => AB* • => AB* / C => AB* / C
• => AB*C/
2. Infix Expression to Postfix Expression Conversion
• Ex.
• A + B * C => A + B * C
• => A + BC* => A + BC*
• => ABC*+
• Ex.
• A * (B + C) - D => A * (B + C) - D
• => A * BC+ - D => A * BC+ - D
• => ABC+* - D => ABC+* - D
• => ABC+*D-
**Postfix Expression does not contain Parentheses
2. Infix Expression to Postfix Expression Conversion

Symbol Priority

*/ 3

+- 2

( 1
Infix to Postfix Conversion Algorithm:
1. Assign priorities to all the operators.
2. Add symbol ‘#’ at the end of the infix expression.
3. Scan the infix expression, character by character, from left to right until the end.
4. {If the character is an Operand, Then add it to the postfix expression.
5. If the character is a Left Parentheses ‘(’, Then push it into Stack.
6. If the character is an Operator, Then,
If (Priority of Operator) > (Priority of the Character in the Top of Stack),
{Then, push the operator into Stack.}
Else,
{While ((Priority of Operator) <= (Priority of the Operator in the Top of Stack))
{Pop operators from the stack and add it to the postfix expression.}
Push the operator into Stack.}
7. If the character is a Right Parentheses ‘)’, Then pop an operator from the Stack
and add it to postfix expression, until a Left Parentheses ‘(’ is encountered.
8. Pop the Left Parentheses, but do not added it to the postfix expression.
9. If the character is ‘#’, Then pop all the operators from the stack and add them to the
postfix expression and Stop.}
• Stack is used for Postfix Conversion
• A * (B + C) - D ==> A * (B + C) – D #

A*(B+C)–D#

+
STACK

( Postfix Expression

*- ABC + * D -
2. Infix Expression to Postfix Expression Conversion

• Prove the following using Stack Data Structure


• (A – B/C)*(A/K-L) => ABC/-AK/L-*
• A*(B-(C/(D-E))*F) => A B C D E - / F * - *
• ((A-B)+C)/(D-E*F/G)+H => A B - C + D E F * G / - / H +
2. Evaluation of Postfix Expression

1. Add symbol ‘#’ at the end of the Postfix Expression.


2. Scan the Postfix Expression, character by character, from left to right until the end.
3. {If the character is an Operand, Then Push it into the Stack.
4. If the character is an Operator, ɸ, Then,
{Pop twice to obtain operands, A & B, from the Stack, Where A is obtained by the
first pop operation and B is obtained by the second pop operation.
Obtain a Result by evaluating B ɸ A.
Push the Result into the Stack.
Do not Push the Operator, ɸ.}
5. If the character is ‘#’, Then pop all the operands from the stack to give the value of the
postfix expression and Stop.
6. }
• Stack is used for Evaluating Postfix Expression
• A * (B + C) - D ==> ABC+*D- => 234+*5-
234+*5-#
4 7 = 3+4
STACK

735 Result =
14 = 2 * 79
29
14 9 =14 - 5
3. Infix Expression to Prefix Expression Conversion
• In Prefix Expression, an operator is placed before its two
operands.
• Ex.
• Ex.
• A + B - C => A + B - C
• A+B => +AB
• => +AB - C => +AB - C
• B+A => +A+
• => -+ABC
• A-B => -AB
• B-A => -BA • Ex.
• A/B => /AB • A * B / C => A * B / C
• A*B => *AB • => *AB / C => *AB / C
• => /*ABC
3. Infix Expression to Prefix Expression Conversion
• Ex.
• A + B * C => A + B * C
• => A + *BC => A + *BC
• => +*ABC
• Ex.
• A * (B + C) - D => A * (B + C) - D
• => A * +BC - D => A * +BC - D
• => *A+BC - D => *A+BC - D
• => -*A+BCD
**Prefix Expression does not contain Parentheses
3. Infix Expression to Prefix Expression Conversion

Symbol Priority

*/ 3

+- 2

) 0
1.
Infix to Prefix Conversion
Assign priorities to all the operators.
Algorithm:
2. Add symbol ‘#’ at the Beginning of the infix expression E.
3. Scan the infix expression, character by character, from Right to Left until the end.
4. Ch = get_next_char(E).
5. While (ch!=‘#’)
6. { if(ch = = ‘)’, then push (ch) into Operator Stack.
7. if(ch = =‘(’, then
8. do { ch = pop( ) from the Operator Stack.
9. push(ch) into the Display Stack.
10. } while (ch!=‘)’.
11. If(ch = = operator)
12. {if(priority of ch >= priority of character on the Top of Operator Stack)
13. { push(ch) into Operator Stack}
14. else
15. {do{ch-2 = pop( ) from the Operator Stack.
16. push(ch-2) into the Display Stack.
17. }While (priority of ch < priority of character on the Top of the Operator Stack)}
18. push(ch) into Operator Stack.}}
Infix to Prefix Conversion Algorithm:

19. If (ch = = ‘#’) then


20. { While(!emptystack(Operator Stack)
21. {ch = pop( ) from the Operator Stack
22. push(ch) into Display Stack
23. }
24. While (!emptystack(Display Stack)
25. {ch=pop( ) from the Display Stack
26. print(ch)
27. }
28. }
• Stack is used for Prefix Conversion
• A * (B + C) - D ==> # A * (B + C) – D START
-
#A*(B+C)–D
*

Operator Stack
A
Display Stack

+
B + Prefix Expression
C *)
D - - * A + B C D
3. Infix to Prefix Expression Conversion

• Prove the following using Stack Data Structure


• (A – B/C)*(A/K-L) => */A – BC-/AKL
• A*(B-(C/(D-E))*F) => *A-B*/C-DEF
• ((A-B)+C)/(D-E*F/G)+H => +/+-ABC-D/*EFGH
3. Evaluation of Prefix Expression
1. Add symbol ‘#’ at the Beginning of the Prefix Expression.
2. Scan the Prefix Expression, character by character, from Right to Left
until the end.
3. {If the character is an Operand, Then Push it into the Stack.
4. If the character is an Operator, ɸ, Then,
{Pop twice to obtain operands, A & B, from the Stack, Where A is obtained by the
first pop operation and B is obtained by the second pop operation.
Obtain a Result by evaluating A ɸ B.
Push the Result into the Stack.
Do not Push the Operator, ɸ.}
5. If the character is ‘#’, Then pop all the operands from the stack to give the value of the
postfix expression and Stop.
6. }
• Stack is used for Evaluating Prefix Expression
• A * (B + C) - D ==> #-*A+BCD =>#-*2+345
START
#-*2+345

9
Stack

2
3 7=3+4
47
14 14 = 2 * 7
95 9 = 14 - 5
4. Function Call

Free Space for local variables, function calls etc.


Stack
Heap Free Space for Dynamic Memory Allocation

Global Variables Space for Global Variables

Code Section Space for Executable binary Code

Memory Map of a C Program


4. Function Call

void main( )
{
int x=22; main( ) Activation Record or
x=22 Frame for main( )
printf(“%d”,x);
return; Heap
}
Global Variables
22 void main( )
{printf(“%d”,x);
return;}
4. Function Call

Activation Record / Frame contains


• Address of the caller function,
• Arguments to called functions,
• Local variables,
• Return values,
• Return address etc.
4. Function
Call 5.func1( )
x=23
x=22 RA=3
1.main( )
x=22 y=23
y
Heap
Global Variables

1.void main( ) 5. int func1(x)


2.{int x=22,y; 6.{x++;
3. y=func1(x); 7. return x;}
4. return;}
4.1 Recursion
• It is a technique to solve a Big Problem by reducing
the Big Problem into simpler problem and then using
the solutions of the simpler problems to find the
solution of the Big Problem.
• Ex. Computing the factorial of an Integer 5
• 5! = 5*4!
• 4! = 4*3!
• 3! = 3*2!
• 2! = 2*1!
• 1! =1*0!
• 0! = 1 and Stop
4.1 Recursion
• Ex. Computing the factorial of an Integer ‘n’
n! = n*(n-1)!
(n-1)! = (n-1)*(n-2)!
(n-2)! = (n-2)*(n-3)!
…………
…………
0! = 1 & Stop
Base Case:
It stops the creation of the simpler version of the problem
4.1 Recursion

• This problem solving technique is implemented by


making a function to call itself repeatedly until one or
more base cases are encountered.
4.1 Recursion

1. int fact ( int n )


2. { Recursion is
3. if (n = = 0) /*base case*/ implemented using
4. return 1; Stack
5. else
6. return (n*fact (n-1));
7. }
1.void main( )
4.1 Recursion 5.fact(n-1)
2.{ int n=3,y; n = 0 RVRV=1 RA=9
3. y = fact(n); 5.fact(n-1)
4. return;} n = 1 RV RV=1 RA=9
/////////////////////////////
5.fact(n-1)
5. int fact(n)
6. { if(n = = 0) //base case n = 2 RV RV=2 RA=9
7. return 1; 5.fact(n)
8. else n = 3 RV RV=6 RA=3
9. return (n*fact(n-1));}
1.main( )
n=3 y=6
4.1 Recursion

1
2 1
3 2 31
A B C

Three Elements
4.1 Recursion

1
2 3
A B C
4.1 Recursion

1 2 3
A B C
4.1 Recursion

2
1 3
A B C
4.1 Recursion

1
2
3
A B C
4.1 Recursion

1
2
A B C

Two Elements
4.1 Recursion

2 1
A B C

1. A→B
4.1 Recursion

1 2
A B C

2. A → C
4.1 Recursion

1
2
A B C

3. B → C
4.1 Recursion

1
A B C

One Element
4.1 Recursion

1
A B C

A→C
B→C

1
A B C

Reserved Position for Reserved Position for


Poping an Element Pushing an Element
B→C

1
A B C

Reserved Position for Reserved Position for


Poping an Element Pushing an Element
B→C

1
A B C

Reserved Position for Reserved Position for


Poping an Element Pushing an Element
B→C

1
B A C

Reserved Position for Reserved Position for


Poping an Element Pushing an Element
B→A

1
B A C

Reserved Position for Reserved Position for


Poping an Element Pushing an Element
B→A

1
B C A

Reserved Position for Reserved Position for


Poping an Element Pushing an Element
4.1 Recursion

Function ( 1, A, B, C )
First Parameter = No. of elements to be Shifted
Second Parameter is the Stack from which elements is
to be Poped.
Third Parameter is the Stack that is used for helping
the shifting operation.
Fourth Parameter is the Stack that is to be used for
Pushing the elements.
4.1 Recursion
Function ( 1, A, B, C )

A→C
=>implies that one element has to be poped from Stack A
and then pushed into Stack C.
=>implies that Stack B is used for helping the Shifting.
4.1 Recursion
Function ( 1, A, C, B )

A→B
4.1 Recursion
Function ( 1, B, A, C )

B→C
Function ( 2, A, B, C )
=>implies that two element has to be poped from Stack A
and then pushed into Stack C.
=>implies that Stack B is used for helping the Shifting.
Function ( 2, A, B, C )

1
2
A B C
Function ( 2, A, B, C )

A→B

1
2
A B C
Function ( 2, A, B, C )

A→B

1
2
A C B
Function ( 2, A, B, C )

Function ( 1, A, C, B )

A→B

2 1
A C B
Function ( 2, A, B, C )

Function ( 1, A, C, B )

A→B
A→C

2 1
A C B
Function ( 2, A, B, C )

Function ( 1, A, C, B )

A→B
A→C

2 1
A B C
Function ( 2, A, B, C )

Function ( 1, A, C, B ) Function ( 1, A, B, C )

A→B A→C

1 2
A B C
Function ( 2, A, B, C )

Function ( 1, A, C, B ) Function ( 1, A, B, C )

A→B A→C
B→C

1 2
A B C
Function ( 2, A, B, C )

Function ( 1, A, C, B ) Function ( 1, A, B, C )

A→B A→C
B→C

2
1
C
B A
Function ( 2, A, B, C )
1 3
Function ( 1, A, C, B ) 2 Function ( 1, B, A, C )
Function ( 1, A, B, C )
A→B B→C
A→C

1
2
C
B A
TowerHonoi(n, A, B, C)
{
If(n==1), then
{ A→C. /*pop( ) from A & push( ) into C*/
return.
}
Else
{TowerHonoi((n-1), A, C, B).
TowerHonoi(1, A, B, C).
TowerHonoi((n-1), B, A, C).
}
return.
}
TH(3,A,B,C) 1
2
TH(2,A,C,B) TH(2,B,A,C)
TH(1,A,B,C)

3 4 5
TH(1,A,B,C) TH(1,A,C,B) TH(1,C,A,B)

A→C A→B C→B


TH(3,A,B,C)
TH(2,A,C,B) TH(2,B,A,C)
TH(1,A,B,C)
6

A→C
TH(3,A,B,C)
7
TH(2,A,C,B) TH(2,B,A,C)
TH(1,A,B,C)

8 9 10
TH(1,B,C,A) TH(1,B,A,C) TH(1,A,B,C)

B→A B→C A→C


Queue Data Structure

• In Queue Data Structure, the data element that is inserted


first is also the one that is deleted first.
• Insertion takes place only at one end called rear.
• Insertion operation is called Enqueue.
• Deletion takes place only at one end called front.
• Deletion operation is called Dequeue.
Queue Data Structure
Enqueue Operation
RearRearRear

1 2 3

Front
Queue Data Structure
Dequeue Operation
Rear

1 2 3

Front
Front Front
Front
Queue Data Structure
Circular Queue Operation
RearRearRear
Rear
Rear

6 7 4 5

Front
Front Front
Front
Queue Data Structure
• Operations on Queue:
• CreateEmptyQ( ),
• EnQueue( ),
• DeQueue( ),
• IsQEmpty( ),
• IsQFull( ),
• GetRear( ),
• GetFront( ),
• MakeEmpty( ).
Queue Data Structure

• Queue can be implemented using array and linked list


Queue Data Structure
• Array implementation of Queue
• CreateEmptyQ( )
int maxsize=40; Rear = -1
A[39]
int queue[maxsize]; A[0] A[1]

int front = rear = -1; 1 2 3


int Qsize = 0;
Front = -1
Queue Data Structure
Enqueue Operation
RearRearRear

1 2 3

Front
Queue Data Structure
• EnQueue( )
{
if (IsQFull)
print “can’t insert”
else
{ rear = rear + 1;
queue[rear]=data;
Qsize = Qsize + 1;}
}
Queue Data Structure
• int DeQueue( )
{ int x;
if(IsQEmpty( ))
print “ Can’t delete”
Else
{front = front+1;
x = queue[front];
Qsize = Qsize - 1;}
return(x);
}
Queue Data Structure

• IsQEmpty( )
{if(front == rear) //if (Qsize = = 0)
return 1;
Else
return 0;
}
Queue Data Structure

• IsQFull( )
{if(rear == max-1)
return 1;
Else
return 0;
}
Queue Data Structure

• Int GetRear( )
{if(IsQEmpty( ))
print “Queue is Empty”
Else
return (queue[rear]);
}
Queue Data Structure

• Int GetFront( )
{if(IsQEmpty( ))
print “Queue is Empty”
Else
return (queue[front]);
}
Queue Data Structure

• Linked list implementation of Queue


• **Home Work
Circular Queue
A[0]
A[n-1] A[1]

A[6] A[2]

A[5]
A[3]
A[4]
Maxsize of Q = n
Circular Queue
Rear
Empty
Empty
A[0] A[1] A[2] A[3] A[4]

1 2 3 4 5

MaxSize of Q = 5
Front Qsize = 2
No. of Empty Space = 3
Rear Circular Queue
Empty

A[0] A[1] A[2] A[3] A[4]

1 2 3 4 5

MaxSize of Q = 5
Front Qsize = 2
No. of Empty Space = 3
Rear Circular Queue
Empty

A[0] A[1] A[2] A[3] A[4]

1 2 3 4 5

MaxSize of Q = 5
Front Qsize = 0
No. of Empty Space = 5
Circular Queue
Rear Empty

A[0] A[1] A[2] A[3] A[4]


If (rear == (n-1))
6 2 3 4 5 rear = rear mod (n-1)

Front i.e., rear = 4 mod 4 = 0


Circular Queue
Rear Empty

A[0] A[1] A[2] A[3] A[4]

6 2 3 4 5 If (front == (n-1))
front = front mod (n-1)

Front i.e., front = 4 mod 4 = 0


Applications of Queue Data Structure

• Waiting list for single shared resources like CPU,


printer etc.
• Used as buffers in multimedia players
• Used for handling interrupts in Operating systems.
Non-Linear Data Structures
• Graphs and Trees.
• They are used to represent network or hierarchical
relationships among real world entities.
• Network relationship like network of roads, friends,
terrorists, institutes etc.
• Hierarchical relationship like family tree, directory,
organizational hierarchy etc.
Graphs
Graph
Definition:
A graph, G, consists of a set of non-empty set of
vertices/nodes, V, and a set of edges, E. A E

i.e., G = ( V, E )
B

For the given graph, D

C
Set V = {A, B, C, D, E}
Set E = {(AB), (AC), (AE), (BC), (CD), (DA), (ED)}
Graph
E
Node or Vertex, E

Edge or Arch,
• Represented by a pair of vertices, (DE).
D
• Undirected edge is represented by a pair
of unordered vertices, (DE) = (ED).

• A graph with only undirected edges is called an


Undirected or Bidirectional Graph.
Graph
• Route Map between towns, A, B, C, D & E.

A E

Undirected or Bidirectional Graphs


Graph
E
Node or Vertex, E

Directed Edge is represented by a pair of


D ordered vertices, (DE) ≠ (ED).

• Node D is called originating node


• Node E is called terminating node
• A graph with only directed edges is called an Directed
Graph.
Graph
• Route Map between towns, A, B, C, D & E.

A E

Directed Graphs
Graph

• An Edge of a graph which joins a node to itself is called


a loop.
Graph
E

D B

• If a pair of nodes contains more than one edge, then such


edges are called parallel edges.
• A graph with parallel edges is called a Multigraph.
Graph
• If there is no more than one edge between pair of nodes of
a graph, then such a graph is called a simple graph.
• A graph in which weights are assigned to every edge is
called a weighted graph.
E
E
4
1 A
A
8
D 6 B
D B

Simple Graph Weighted Graph


Graph
F Isolated Node

D Isolated Node

• A graph must contain vertices, but it may not contain any


edge.
• Such a graph is called Null graph.
Graph
A Null graph.
E

G = ( V, E )
V ={ E, D}
E={ɸ}
D
Graph
• Nodes of an edge are called adjacent nodes or neighbors.
• Ex. For edge (DE), nodes E & E are adjacent nodes.
• Out-degree of a node, E, of a directed
graph, is the number of edges originating
from the node, E. E
• Ex.OD( E ) =1
• In-degree of a node, E, is the number of
F
edges terminating at node E. Ex. ID( E )=1 D
• Degree of a node, E, is the sum of its out-
degree and in-degree. Ex. D( E ) = 1+1=2. B
A
Graph
• In an undirected graph, the degree of a node, E, is the
number of edges incident to the node, E.
• Ex. D ( E ) = 2.
• Ex. D (A) = 2
E

A
F
D

C
B A
Graph
• A Path in a directed graph, is any sequence of edges, such
that the terminal node of any edge in the sequence is the
initial node of the edge, if any, appearing next in the
sequence. E
E
E

F
F
F D
D
D

A
A
A
Path with non-
Cyclic Path distinct edges
Simple Path
Graph
• A Path is represented as given below:
• Path=((Vi1,Vi2), (Vi2,Vi3), (Vi3,Vi4),……..(Vin-2,Vin-1), (Vin-1,Vin)) or
• Path=(Vi1,Vi2,Vi3,Vi4……..Vin-2,Vin-1,Vin)
• P1=((D,E))
• P2=((D,E),(E,F))
• P3=((D,A),(A,E),(E,F),(F,D),(D,A),(A,E),(E,F))

• Path length is the number of edges E

appearing in the path. F


D

A
Graph
• A Path of a digraph, with distinct edges is called a simple
path.
• A Path in which all nodes are distinct is called an
elementary path.
• If there exists a path from node A to node B, then there must be an
elementary path from A to B.
• A Path which originates and ends in the same
E
node is called a cycle.
• A cycle in which a node(except the D
F

originating node) is traversed not more than


once is called elementary cycle. A
Graph
• A graph is connected if and only if there is a simple path
between any two nodes of the graph.
• A graph G is said to be complete if every node A in G is
adjacent to every other node B in G.
• A complete graph with n nodes will have n(n-1)/2 edges.
E

D F

A Complete Graph
Graph
• A Simple digraph is a digraph without parallel edges.
• Simple digraph which does not have any cycle is called
Directed Acyclic Graph(DAG).
E

F
D

A
Representation of Graphs

• 1. Adjacency Matrix.
• 2. Adjacency List.
Representation of Graphs

1. Adjacency Matrix:

If G is a simple graph with n nodes (v1, v2…vn) then its


adjacency matrix A = (aij) is a n*n matrix defined as

1 if vi is adjacent to vj,
aij =
0 otherwise.
Representation of Graphs
1. Adjacency Matrix for DAG:
C
Adjacent Nodes
A B C D
A 0 0 0 0 D

B 1 0 1 0 B

C 0 0 0 1
D 1 0 0 0 A

Nodes
Representation of Graphs
1. Adjacency Matrix:
C
Adjacent Nodes
A B C D
A 1 0 0 0 D

B 1 0 1 1 B

C 0 0 0 1
D 1 0 0 0 A

Nodes
Representation of Graphs
1. Adjacency Matrix for undirected graph:
C
Adjacent Nodes
A B C D
A 0 1 0 1 D

B 1 0 1 1 B

C 0 1 0 1
D 1 1 1 0 A

Nodes
Adjacency Matrix for undirected graph is Symmetric, aij = aji
Representation of Graphs
1. Adjacency Matrix for a Weighted Graph:
C
Adjacent Nodes 7
A B C D 2
A 0 0 0 0 D

B 5 0 2 0 B

C 0 0 0 7 5 1
D 1 0 0 0 A

Nodes
Powers of Adjacency Matrix: V4
V1 V2 V3 V4
V1 0 1 0 1

V2 1 0 0 0
V3
V3 1 1 0 1 V1
V4 0 1 0 0

V2

A = aij
• Adjacency matrix A = aij shows the number of path, with
path length =1, that exits from node Vi to Vj.
Powers of Adjacency Matrix: V4
V1 V2 V3 V4
V1 1 1 0 0

V2 0 1 0 1
V3
V3 1 2 0 1 V1
V4 1 0 0 0

V2

A2 = aij (2)

• Similarly, adjacency matrix A2 = aij (2) shows the number of paths,


with path length =2, that exits from node Vi to Vj.
Powers of Adjacency Matrix:
aij (2) is computed as:
σ 𝑛=4
aij (2) = 𝑘=1 𝑎𝑖𝑘 𝑎𝑘𝑗

For any k, aikakj = 1, if & only if aik=1 & akj=1

• Similarly, adjacency matrix An = aij (n) shows the number of


paths, with path length = n, that exits from node Vi to Vj.
Powers of Adjacency Matrix: V4
V1 V2 V3 V4
V1 1 1 0 1

V2 1 1 0 0
V3
V3 2 2 0 1 V1
V4 0 1 0 1

V2

A3 = aij (3)

• Similarly, adjacency matrix A3 = aij (3) shows the number of paths,


with path length =3, that exits from node Vi to Vj.
Powers of Adjacency Matrix: V4
V1 V2 V3 V4
V1 1 2 0 1

V2 1 1 0 1
V3
V3 2 3 0 2 V1
V4 1 1 0 0

V2

A4 = aij (4)

• Similarly, adjacency matrix A4 = aij (4) shows the number of paths,


with path length =4, that exits from node Vi to Vj.
Powers of Adjacency Matrix:
Let Bn be defined as:
𝐵𝑛 = 𝐴 + 𝐴2 + 𝐴3 … + 𝐴𝑛

• bij of Bn shows the number of paths, of path length <=n,


that exists from node Vi to Vj.
• Bn helps to know if any node Vj is reachable from any
other node Vi.
• If bij = 0, then node Vj is not reachable from Vi.
• If bij ≠ 0, then node Vj is reachable from Vi.
V1 V2 V3 V4
3 5 0 3 V1

3 3 0 2 V2

Bn = 6 8 0 5 V3

2 3 0 1 V4
Path Matrix (Reachability Matrix):
Let G = ( V, E ) be a simple digraph with n nodes.
Then its path matrix P is defined as:

1 if there exists a path from node Vi to Vj,


pij =
0 otherwise.
Path Matrix (Reachability Matrix):

Path matrix P can be obtained from Bn.


V1 V2 V3 V4 V1 V2 V3 V4
3 5 0 3 V1 1 1 0 1 V1
3 3 0 2 V2 1 1 0 1 V2
Bn = 6 8 0 5 V3
P= 1 1 0 1 V3
2 3 0 1 V4 1 1 0 1 V4
Computation of Path Matrix using Warshall Algorithm:

Operator AND (˄) is defined as


0 1
0 0 0
1 0 1

Operator OR (˅) is defined as


0 1
0 0 1
1 1 1
Computation of Path Matrix using Warshall Algorithm:

Boolean Sum of Boolean Matrices A and B is written as


C=A˅B
The element of C is cij
cij = aij ˅ bij

Boolean Product of Boolean Matrices A and B is written as


D=A˄B n
The element of D is dij = ˅ (aik ˄ bkj)
k=1
Computation of Path Matrix using Warshall Algorithm:

• A ˄ A = A(2),
=> If aij(2) =1, then there is at least one path of length two
from node Vi to Vj, else there is no path.
• A ˄ A(r-1) = A(r)
=> If aij(r) =1, then there is at least one path of length r from
node Vi to Vj, else there is no path.
Computation of Path Matrix using Warshall Algorithm:

• So, path matrix is given as n


P = A ˅ A(2) ˅ A(3) …..˅ A(n) = ˅ (A (k))

k=1
V4
V1 V2 V3 V4
V1 1 1 0 0

V2 0 1 0 1
V3
V3 1 1 0 1 V1
V4 1 0 0 0

V2

A(2) = aij (2)


V4
V1 V2 V3 V4
V1 1 1 0 1

V2 1 1 0 0
V3
V3 1 1 0 1 V1
V4 0 1 0 1

V2

A(3) = aij (3)


V4
V1 V2 V3 V4
V1 1 1 0 1

V2 1 1 0 1
V3
V3 1 1 0 1 V1
V4 1 1 0 0

V2

A(4) = aij (4)


V4
V1 V2 V3 V4
V1 1 1 0 1

V2 1 1 0 1
V3
V3 1 1 0 1 V1
V4 1 1 0 1

V2

P = A ˅ A(2) ˅ A(3) ˅ A(4)


Computation of Path Matrix using Warshall Algorithm:
Procedure warshall (adjacency_mat A, path_mat P, nodes n)
{
integer i,j,k;
P=A;
for(k=1 to n)
{for(i=1 to n)
{for(j=1 to n)
P[i,j]= P[i,j] ˅ (P[i,k] ˄ P[k,j]);
}
}
}
Limitations of Adjacency Matrix:

• It’s a static implementation


• Deletion and Insertion of nodes are difficult for large
graphs
Representation of Graphs B

2. Adjacency List for Digraph:


D
A
A B C X
B C D X
C
C D X
D
A B X
Representation of Graphs B

2. Adjacency List for Undirected


Graph:
D
A

A B C X
C
B A C D X
C A B D X
D
B C X
Representation of Graphs B

2. Adjacency List for Weighted 2 1


Graph:
A
4 D

A C 7 X 5
7 C
B A 2 X
C
B 4 X
D
B 1 C 5 X
Graphs Traversals

1. Breadth First Search(BFS),


2. Depth First Search(DFS)
1. Breadth First Search(BFS):
Queue B
B A D C

Visited Status D
A
A B C D
01 01 01 01
C

Print B A D C
1. Breadth First Search(BFS):
Print B
Level-0
B A D E C F G H

A D
Level-1

E C F

Level-2
G
H
Level-3
1. Breadth First Search(BFS) Algorithm:

1. Set the visited status of each node of the graph to 0.


2. Enqueue the starting node and set its visited status to1.
3. Repeat Step-4 and Step-5 until Queue is Empty
4. Dequeue a node, N, and print its data
5. Enqueue all the unvisited adjacent nodes of node, N,
and set their visited status to 1.
1. Breadth First Search(BFS) Algorithm:

1. Time Complexity = O(V+E) //adjacency list


2. Space Complexity = O(bd) //adjacency list
Where, b = branching factor
d = deepest level of the graph
1. Breadth First Search(BFS) Algorithm:
• Single Source Shortest Path in an Unweighted Graph
• It gives the shortest path from a given node to all other
nodes of the graph.
B

D
E A

C
1. Breadth First Search(BFS) Algorithm:
Queue
B E A D C
From Nodes
# B B A A
Visited Nodes
B
01 01 01 01 01
A B C D E

Shortest Paths from B to all nodes: D


1. B to E => B->E = 1 E A

2. B to A => B->A = 1
3. B to D => B->A->D = 2
4. B to C => B->A->C = 2 C
2. Depth First Search(DFS):
B

D
DC A
BA
Stack
C
Visited Status

1 0 10 1 0 1 0
Print B D C A
A B C D
2. Depth First Search(DFS):
B

Stack D
E A

Visited Status
F C
Print

B D C F G A E G
2. Depth First Search(DFS) Algorithm:
1. Set the visited status of each node of the graph to 0.
2. Push the starting node into Stack and set its visited status
to1.
3. Pop the node, N, located at the top of stack and print the
data of the node.
4. Repeat Step-5 & Step-6 until Stack is Empty
5. Push all unvisited adjacent nodes of the node, N, into the
stack and set its visited status to1.
6. Pop the node located at the top of stack as N & Print its
data.
7. End.
2. Depth First Search(DFS) Algorithm:

1. Time Complexity = O(V+E) //adjacency list


2. Space Complexity = O(d) //adjacency list
where, d = deepest level of the graph
2. Depth First Search(DFS) Algorithm:
Topological Sorting of DAG:

• It is a linear ordering of the nodes of a DAG, G, such that


if there is an edge(A,B) in G, then node A must always
appear before node B in the linear ordering.
• It is achieved using DFS.
2. Depth First Search(DFS) Algorithm:
Topological Sorting of DAG:
D
A F G

E
B C

1. A B D C E F G
2. B A D C E F G
2. Depth First Search(DFS) Algorithm: Start
Topological Sorting of DAG:
D
A F G

E A 0 1
B C B 0 1
C 0 1
B D 0 1
A E 0 1
C F 1
E 0
GE G 0 1
D
FC F
DAB G B A C E D F G
Disjoint Set Data Structure
• Set is a collection of distinct elements.
• S1 = {1, 2, 3, 4}. 1 4

2 3

• If S1 intersection S2 is empty, then they are disjoint sets.


Disjoint Set Data Structure

• It’s a data structure that supports three operations


• Makeset
• It makes a set with only one element
• Findset
• It returns the representative element of a set
• Unionset
• It merges two sets into one
Disjoint Set Data Structure

• Given a list of integers, L= (1,2,3,4,5,6,7).


• Makeset(L)

{*1} {*2} {*3} {*4}

{*5} {*6} {*7}

Representative Element of the Set


Disjoint Set Data Structure
• Given a list of integers, L= (1,2,3,4,5,6,7,8).
• Makeset(L)

*1 *2 *3 *4

*5 *6 *7 *8

Graphical Representation of Disjoint Sets


Disjoint Set Data Structure
• Findset(1) => 1 • Findset(3) => 3 • Findset(5) => 5
• Findset(2) => 2 • Findset(4) => 4 • Findset(6) => 6

*1 *2 *3 *4

*5 *6 *7 *8

Graphical Representation of Disjoint Sets


Disjoint Set Data Structure
• Unionset(1, 2) => Unionset(findset(1), findset(2))
• => Unionset(1, 2)

*1 *2 *3 *4

*5 *6 *7 *8

Graphical Representation of Disjoint Sets


Disjoint Set Data Structure
• Unionset(1, 2) => Unionset(findset(1), findset(2))
• => Unionset(1, 2)

*1 2 *3 *4

*5 *6 *7 *8

Graphical Representation of Disjoint Sets


Disjoint Set Data Structure
• Unionset(2,3) => Unionset(findset(1), findset(3))
• => Unionset(1, 3)

*1 2 *3 *4

*5 *6 *7 *8

Graphical Representation of Disjoint Sets


Disjoint Set Data Structure

• Unionset(3,4); Unionset(5,6); Unionset(7,8);

*1 2 *3 4

*5 6 *7 8
Disjoint Set Data Structure
• Unionset(2,4) => Unionset(findset(2),findset(4))
• => Unionset(1,3);
*1 2 *3 4

*1 *5 6 *7 8

3
2

4
Disjoint Set Data Structure
• Unionset(3,6) => Unionset(findset(3),findset(6))
• => Unionset(1,5);
*1
*5 6 *7 8

3
2

• Since the size of set *1 is bigger than that of set *5, make
the representative of set *1 as the representative of the
new set obtained after unionset operation.
Disjoint Set Data Structure
• Unionset(3,6) => Unionset(findset(3),findset(6))
• => Unionset(1,5);

*7 8
*1

3 5
2

4 6
Array Implementation
L = {1,2,3,4,5,6,7,8} Makeset(L):

Representative -1 -1 -1 -1 -1 -1 -1 -1
S => 1 2 3 4 5 6 7 8
=> A set is represented by an index of an array.
=> Minus sign(-) indicates that the associated index is the
representative of the set.
 1 indicates the size of the set.
 Any +ve number in the array indicates the parent of the
index
Array Implementation
L = {1,2,3,4,5,6,7,8} Makeset(L):

Representative -1 -1 -1 -1 -1 -1 -1 -1
S => 1 2 3 4 5 6 7 8

*1 *2 *3 *4

*5 *6 *7 *8
Array Implementation
Unionset(1, 2); Makeset(L):

Representative -2 1 -1 -1 -1 -1 -1 -1
S => 1 2 3 4 5 6 7 8

*1 2 *3 *4

*5 *6 *7 *8
Unionset(2, 3) => Unionset(findset(2), findset(3))
=> Unionset(1,3)
Representative -2 1 -1 -1 -1 -1 -1 -1
S => 1 2 3 4 5 6 7 8

*1 2 *3 *4

*5 *6 *7 *8
Unionset(2, 3) => Unionset(findset(2), findset(3))
=> Unionset(1,3)
Representative -3 1 1 -1 -1 -1 -1 -1
S => 1 2 3 4 5 6 7 8

*1 2 3 *4

*5 *6 *7 *8
Unionset(4, 5); Unionset(6,7); Unionset(4,8)

Representative -3 1 1 -1 -1
-2
-3 4 -1
-2 -1
6 -1
4
S => 1 2 3 4 5 6 7 8

*1 2 3 *4

*5
5 *6 *77 *8
8
Unionset(4,6);

Representative -3 1 1 -1 -1
-5
-2
-3 4 -1
-2
4 -1
6 -1
4
S => 1 2 3 4 5 6 7 8
*4
*1
6
*6
3 5 8
2
7
Unionset(3,6)

Representative -3
4 1 1 -1 -1
-2
-5
-3
-8 4 -1
-2
4 -1
6 -1
4
S => 1 2 3 4 5 6 7 8
*4
*1
1
6
*6
3 5 8
2
7
findset(7); findset(2)

Representative -3
4 1 1 -1 -1
-2
-5
-3
-8 4 -1
-2
4 -1
6 -1
4
S => 1 2 3 4 5 6 7 8
*4

1 6
5 8

7
2 3
Better findset( ) by path compression
Representative -3
4 4 4 -1 -1
-2
-5
-3
-8 4 -1
-2
4 -1
4 -1
4
S => 1 2 3 4 5 6 7 8
*4

1 6
5 8

7
2 3
int findset (int x)
Findset( )
{
If (array[x]<0)
return x;
Else
{ array[x]=findset(array[x]);
return array[x];
}
} Time complexity = O(log m), where
m is the number of union operations
done prior to findset( ).
int findset (int x) Findset( )
{ int rep,y=x;
//find the representative node of node x
Do{
rep=x;
x= array[x];
}While (x>0);
X=rep;
//make all the nodes in the path of x to have the representative node of x as their
representative node
While (array[y]<x)
{
rep = y;
y = array[rep];
array[rep] = x;
} return x;
}
int unionset (int x, int y) = unionset(findset(m),findset(n))
{ Unionset( )
if( x!=y)
{ if(array[x] < array[y]) //size comparison of sets (-8<-6)
{ array[x] += array[y];
array[y] = x;}
else { array[y] += array[x];
array[x] = y;}
if(array[x] == array[y])
{ array[x] += array[y];
array[y] = x;}
return 1; //union done
}
else
return 0; //union not possible
Time complexity = O(1)
}
=> A sequence of ‘f’ findset( ) and ‘m’ unionset( ) operations
takes Ɵ(m + fα(f+m, m)).
 α is an extremely slow growing function
 α is never greater than 4 for any value of ‘f’ & ‘m’.
A D Detecting Cycles in a Graph

B C

A Graph
unionset(1,2);
A D

-1 -1 -1 -1
B C
1 2 3 4
A B C D
Finding cycles in a Graph
A D

B C

A Graph unionset(1,2);

A D

-2 1 -1 -1
B C 1 2 3 4
A B C D
Finding cycles in a Graph
A D

B C

A Graph unionset(2,3);

A D

-2 1 -1 -1
B C 1 2 3 4
A B C D
Finding cycles in a Graph
A D

B C

A Graph unionset(2,3);

A D

-3 1 1 -1
B C 1 2 3 4
A B C D
Finding cycles in a Graph
A D

B C

A Graph unionset(3,4);

A D

-3 1 1 -1
B C 1 2 3 4
A B C D
Finding cycles in a Graph
A D

B C

A Graph unionset(3,4);

A D

-4 1 1 1
B C 1 2 3 4
A B C D
Finding cycles in a Graph
A D

B C unionset(4,1) =unionset(1,1);
returns 0. So cycle detected.
A Graph

A D

-4 1 1 1
B C 1 2 3 4
A B C D
Minimum Spanning Tree
• A Tree is a connected graph without any cycle.
• A tree can be constructed from a graph.
• A tree is a subset of a graph.
A D A D A D

B C B C B C

A Graph
A D
C
B

C
Minimum Spanning Tree
• A Spanning Tree of a graph is a tree that contains all the
nodes of the graph.
A D A D
A D

B C B C
B C

A Graph A D

B C
Minimum Spanning Tree
• Minimum Spanning tree is a spanning tree whose sum of
the weights of all of its edges is minimum.
• Algorithms for MST
• Kruskal’s Algorithm
• Prim’s Algorithm

A
1 D
6 E

3 5
3 1 2
B C F
1 4
Kruskal’s Algorithm
A
1 D
6 E Sort the edges in increasing order
3 5 2 • AD=1
3 1
• BC=1
B C F
1 4 • DC=1
If (Unionset(A,D)) • EF=2
Then add AD Makeset(G)
to result • AB=3
A D E • BD=3
• CF=4
• CE=5
B C F
• DE=6
Minimum Spanning Tree
A
1 D
6 E Sort the edges in increasing order
3
1
5
2 • AD=1
3
B
• BC=1
C F
1 4 • DC=1
• EF=2
1
A D E • AB=3
2 • BD=3
1
B
• CF=4
C F

4 • CE=5
1
• DE=6
Kruskal’s Algorithm
MST-Kruskal(G)
{ mst=empty;
makeset(V); //make disjoin sets using V //O(V)
sort(E); //sort the edges of Graph //O(Elog(E))
for each edge (A,B) from the sorted list of edges //O(E)
{ if (unionset(A,B)) //checking for cycle //~ O(1)
add edge(A,B) to mst; //O(1)
}
return mst;
}
Kruskal’s Algorithm
• If the weights of edges are distinct then MST is unique
• Otherwise there can be many MST.
• Time complexity = O(Elog(E))
• Space Complexity = O(V+E)
Priority Queue
• It is a queue in which each element has a priority.
• Elements with higher priority are processed before the
elements with lower priority.
• If the priorities of the elements are sorted, then enqueue
takes O(n) and dequeue takes O(1).
• If the priorities are not sorted, then enqueue takes O(1)
and dequeue takes O(n).
• The above two implementations are not desirable.
• It can be efficiently implemented using graphs(heap).
Root
Priority Queue

20 Parent/Child 20

45 79
15 19 Leaf

5 7 55 60 87 99
10 9

Max Heap Min Heap


The priority of parent The priority of parent
nodes are always greater nodes are always less
than child nodes. than child nodes.
Array Implementation of Max Heap
• Root node is represented by index, i = 1.
• Left child of node, i, = 2i.
• Right child of node, i, = 2i+1.
• Parent of node, i, = floor(i/2) = i/2. 1 20

2 15 3 19

20 15 19
1 2 3
Max Heap
• Dequeue always takes place at root node, i = 1.
• Enqueue always takes place at the rear, that is, at the leaf
node that occurs after the last element of the array.

1 20

2 15 3 19
Max Heap
• Enqueue
1 25
20
30

2 • Check if Max Heap Property


25
20 30
25
Violated?
• If yes, then swap the child and
parent node.

Q 30
20
25 25
20 25
30
1 2 3
Max Heap
• Enqueue

Enqueue(int data, int rear)


{ Moveup(int i)
If Q is not full {p=i/2; //parent
{ rear++; While((i > 0)&&(Q[p] < Q[i]))
Q[rear]=data; //O(1) { swap(p,i);
Moveup(rear); //log(n) i=i/2;
}
}
}
}
*n=number of elements in Q
Max Heap
• Dequeue
1 30
25

2 20 25
30
3

Q 30
25 20 25
30
1 2 3
Max Heap
• Dequeue
1 30
18

2 20
3 25

4
18
30
Max Heap
• Dequeue
1 18
25

2 20
3 18
25
Max Heap
Movedown(int i)
• Dequeue {
Dequeue( ) While((2*i )<= n)
{ {Lchild=2*i;
If Q is not Empty Rchild=(2*i+1);
{swap(1, rear); //O(1) If(Q[Lchild]>Q[i])
rear--; largest=Lchild;
Movedown(1); //log(n) Else largest=Rchild;
Swap(i,largest);
}
i=largest;
} }
*n=number of elements in Q }
Prim’s Algorithm

A
1 D
6 EE

3 5
3 1 2
B C F
1 4
P=NIL P=NIL P=NIL MST={ }
K= 0 K= ∞ K= ∞ For each vertex,v, of G
1 6 {Key[v]=∞;
A D E Parent[v]=NIL;
Root
3 5 }
3 1 2 Key[root]=0;
Min-Q=V;
B C F
While(Min-Q is not Empty)
1 4 {u=dequeue(Min-Q);
P=NIL P=NIL P=NIL
If(Parent(u)!=NIL)
K= ∞ K= ∞ K= ∞
MST=Union(MST,(u,Parent(u)));
For each adjacent vertex, v, of vertex u
MST={ } if v is in Min-Q & Weight(u,v)<Key(v)
{Parent[v]=u;
Min-Q ={A,B,C,D,E,F} Key[v]=Weight(u,v);}
}
End
MST={ }
P=NIL P=A
P=NIL P=NIL For each vertex,v, of G
Root K= 0 K= 1∞ K= ∞ {Key[v]=∞;

A
1 D
6 E
Parent[v]=NIL;
}
3 5 Key[root]=0;
3 1 2 Min-Q=V;
B
While(Min-Q is not Empty)
C F
{u=dequeue(Min-Q);
1 4 If(Parent(u)!=NIL)
P=A
P=NIL P=NIL P=NIL
K= 3∞ K= ∞
MST=Union(MST,(u,Parent(u)));
K= ∞
For each adjacent vertex, v, of vertex u
if v is in Min-Q & Weight(u,v)<Key(v)
MST={ } {Parent[v]=u;
Key[v]=Weight(u,v);}
Min-Q ={B,C,D,E,F}
={A,B,C,D,E,F}
={D,B,C,E,F} }
End
MST={ }
P=NIL P=A P=D
P=NIL For each vertex,v, of G
Root K= 0 K= 1 K= 6∞ {Key[v]=∞;
Parent[v]=NIL;
A
1 DD
6 E }
Key[root]=0;
3 5
3 1 2 Min-Q=V;
While(Min-Q is not Empty)
B C F {u=dequeue(Min-Q);
P=A
1 4 If(Parent(u)!=NIL)
P=D
P=NIL P=NIL MST=Union(MST,(u,Parent(u)));
K= 3 K= ∞
1 K= ∞ For each adjacent vertex, v, of vertex u
if v is in Min-Q & Weight(u,v)<Key(v)
{Parent[v]=u;
MST={{A,D}}
MST={ } Key[v]=Weight(u,v);}
Min-Q
Min-Q ={B,C,E,F}
={C,B,E,F}
={D,B,C,E,F} }
End
MST={ }
P=NIL P=A P=D
P=C
P=NIL For each vertex,v, of G
Root K= 0 K= 1 K= 65∞ {Key[v]=∞;
A
1 DD
6 E
Parent[v]=NIL;
}
3 5 Key[root]=0;
3 1 2 Min-Q=V;
B C F While(Min-Q is not Empty)
1 {u=dequeue(Min-Q);
P=C
P=A P=D
P=NIL 4 P=C
P=NIL If(Parent(u)!=NIL)
K= 3
1 K= ∞
1 K= 4∞ MST=Union(MST,(u,Parent(u)));
For each adjacent vertex, v, of vertex u
if v is in Min-Q & Weight(u,v)<Key(v)
MST={{A,D}}
MST={{A,D},{D,C}} {Parent[v]=u;
Key[v]=Weight(u,v);}
Min-Q ={B,E,F}
Min-Q ={C,B,E,F}
={B,F,E} }
End
MST={ }
P=NIL P=A P=D
P=C
P=NIL For each vertex,v, of G
Root K= 0 K= 1 K= 65∞ {Key[v]=∞;
A
1 DD
6 E
Parent[v]=NIL;
}
3 5 Key[root]=0;
3 1 2 Min-Q=V;
B C F While(Min-Q is not Empty)
1 {u=dequeue(Min-Q);
P=C
P=A P=D
P=NIL 4 P=C
P=NIL If(Parent(u)!=NIL)
K= 3
1 K= ∞
1 K= 4∞ MST=Union(MST,(u,Parent(u)));
For each adjacent vertex, v, of vertex u
if v is in Min-Q & Weight(u,v)<Key(v)
MST={{A,D},{D,C},{C,B}}
MST={{A,D},{D,C}} {Parent[v]=u;
Key[v]=Weight(u,v);}
Min-Q ={B,F,E}
={F,E} }
End
MST={ }
P=NIL P=A P=D
P=F
P=C
P=NIL For each vertex,v, of G
Root K= 0 K= 1 K= 65∞
2 {Key[v]=∞;
Parent[v]=NIL;
A
1 DD
6 E }
Key[root]=0;
3 5
3 1 2 Min-Q=V;
While(Min-Q is not Empty)
B C F {u=dequeue(Min-Q);
P=C
P=A
1 4 If(Parent(u)!=NIL)
P=D
P=NIL P=C
P=NIL MST=Union(MST,(u,Parent(u)));
K= 3
1 K= ∞
1 K= 4∞ For each adjacent vertex, v, of vertex u
if v is in Min-Q & Weight(u,v)<Key(v)
MST={{A,D},{D,C},{C,B}}
MST={{A,D},{D,C},{C,B},{C,F }} {Parent[v]=u;
Key[v]=Weight(u,v);}
Min-Q ={F,E}
={E} }
End
MST={ }
For each vertex,v, of G
P=NIL P=A P=D
P=F
P=C
P=NIL
Root K= 0 {Key[v]=∞;
K= 1 K= 5∞
62
Parent[v]=NIL;
A
1 DD
6 EE }
Key[root]=0;
3 5
3 1 2 Min-Q=V;
While(Min-Q is not Empty)
B C F {u=dequeue(Min-Q);
P=C
P=A
1 4 P=C If(Parent(u)!=NIL)
P=NIL
P=D P=NIL MST=Union(MST,(u,Parent(u)));
K= 3
1 K= 1∞
K= K= 4∞ For each adjacent vertex, v, of vertex u
if v is in Min-Q & Weight(u,v)<Key(v)
{Parent[v]=u;
Key[v]=Weight(u,v);}
MST={{A,D},{D,C},{C,B},{C,F }} },{F,E}}
}
End
Min-Q ={E}
={ }
MST={ }
For each vertex,v, of G //O(V)
{Key[v]=∞; Time Complexity
Parent[v]=NIL; = O(Vlog(V)+Elog(V))
}
Key[root]=0; = O(V+E(log(V))
Min-Q=V; //Vlog(V) = O(Elog(V))
While(Min-Q is not Empty)//V
{ u=dequeue(Min-Q); //log(V) Space Complexity
If(Parent(u)!=NIL) = O(2V+V+E)
MST=Union(MST,(u,Parent(u))); //1
For each adjacent-vertex, v, of vertex u //E = O(V+E)
{if v is in Min-Q & Weight(u,v)<Key(v) //1
{Parent[v]=u; //1
Key[v]=Weight(u,v);} //log(V)
}
End
Single Source Shortest Paths

• Given a weighted digraph G=(V, E), We have to find the


shortest path from a given source vertex, s𝝐𝑽 to each
vertex v𝝐𝑽.
• Weight of an edge can be either –ve or +ve.
Single Source Shortest Paths
• Weight of a Path P=(v0, v1…. vk) is denoted as w(P).
𝒌
• W(P)= 𝒊=𝟏 𝒘(𝒗𝒊−𝟏 , 𝒗𝒊 )
σ

• Shortest Path weight δ(u,v) from u to v is defined as:

min{w(P)} if there is a path from u to v


δ(u,v)=
∞ otherwise
Single Source Shortest Paths
• Shortest path cannot have –ve or +ve weight cyclic paths.
δ=3 δ= -1
-4
A B

3 4
δ=0 δ=5 6 δ=11 δ= -∞
S 5 D
8 G
C
-3 δ= ∞
7 2
2 I
3 δ= ∞
E F H 3
δ= -∞ -6 J
δ= -∞ -8 δ= ∞
Single Source Shortest Paths
• Paths from S to C
• {S,C}= 5
• {S,C,D,C}=5+6-3 = 8 (a cyclic path with +ve weight)
• {S,C,D,C,D,C}=5+6-3+6-3 = 11
• Infinite paths, so, δ = 5
• Paths from S to E
• {S,E}= 2
• {S,E,F,E}=2+3-6= -1 (a cyclic path with -ve weight)
• {S,E,F,E,F,E}=2+3-6+3-6= - 4
• Infinite paths, so, so, δ = -∞
Relaxation

• For each vertex, v, and attribute, d[v], is maintained.


• d[v] is the upper bound on the weight of a shortest path
from source, s, to v.
• d[v] = shortest path estimate.
• For each vertex, v, another attribute, p[v], is maintained.
• p[v] is the predecessor of node v.
Relaxation
• Relax operation is used to reduce the shortest path
estimate d[v] and update the predecessor p[v].
• It’s the primary operation used.
• Relax(u,v,w)
{ if (d[u]+w(u,v)) < d[v])
{ d[v] = d[u]+w(u,v);
p[v]=u;
}
}
• *Time complexity = O(1)
Relaxation Operation
P=A
P=B
u
d=5
d= 7
9
2
u v

Relax(u,v,w) Relax(u,v,2)
{ if (d[u]+w(u,v)) < d[v]) if (5+2) < 9)
{ d[v] = d[u]+w(u,v); {
p[v]=u; d[v] = 7
} p[v] = u;
} }
Initialization
Initialize-Single-Source(G, source)
{
For each vertex, v𝜖𝑉
{ d[v]=∞;
p[v]=NIL;
}
d[source]=0;
}
* Time complexity =O(V)
Single Source Shortest Path Algorithms

1. Bellman-Ford algorithm
2. Dijkstra’s algorithm
Bellman-Ford algorithm

• It computes the shortest path if there is no cyclic path


with –ve weight in a graph.
• If there is any cyclic path with –ve weight in the graph, it
detects it and reports that there is no shortest path.
• It uses dynamic programming
Bellman-Ford algorithm
5 Bellman-Ford(G,w,s)
{Initialize-single-source(G,s); //O(V)
-2
6 B D For i=1 to (V-1) //O(V)
-3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
9
{If ((d[u]+w(u,v)) < d[v]
Return false;}
Return True;
}
Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(B.d + W(B,D)) < D.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(B.d + W(B,C)) < C.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(B.d + W(B,E)) < E.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(D.d + W(D,B)) < B.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(C.d + W(C,D)) < D.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(C.d + W(C,E)) < E.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(E.d + W(E,D)) < D.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P = NIL
5 P = NIL Bellman-Ford(G,w,s)
d=∞ d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(E.d + W(E,A)) < A.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm
P P= =NIL
A 5 P = NIL Bellman-Ford(G,w,s)
dd == ∞
6 d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P = NIL 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=∞ d=∞
Return false;}
(A.d + W(A,B)) < B.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=1 Bellman-Ford algorithm

P=A
5 P = NIL Bellman-Ford(G,w,s)
d=6 d=∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
PP= =NIL
A 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
dd == ∞
7 d=∞
Return false;}
(A.d + W(A,C)) < C.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 PP==NIL
B Bellman-Ford(G,w,s)
d=6 dd == 11
∞ {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=7 d=∞
Return false;}
(B.d + W(B,D)) < D.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=B Bellman-Ford(G,w,s)
d=6 d = 11 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P = NIL {If ((d[u]+w(u,v)) < d[v]
d=7 d=∞
Return false;}
(B.d + W(B,C)) < C.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=B Bellman-Ford(G,w,s)
d=6 d = 11 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 PP==NIL
B {If ((d[u]+w(u,v)) < d[v]
d=7 dd == ∞
2
Return false;}
(B.d + W(B,E)) < E.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=B Bellman-Ford(G,w,s)
d=6 d = 11 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(D.d + W(D,B)) < B.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 B
P=C Bellman-Ford(G,w,s)
d=6 dd== 11
4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(C.d + W(C,D)) < D.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=C Bellman-Ford(G,w,s)
d=6 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(C.d + W(C,E)) < E.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=C Bellman-Ford(G,w,s)
d=6 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(E.d + W(E,D)) < D.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=C Bellman-Ford(G,w,s)
d=6 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(E.d + W(E,A)) < A.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=C Bellman-Ford(G,w,s)
d=6 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(A.d + W(A,B)) < B.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=2 Bellman-Ford algorithm

P=A
5 P=C Bellman-Ford(G,w,s)
d=6 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
(A.d + W(A,C)) < C.d Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=3 Bellman-Ford algorithm

P=D
5 P=C Bellman-Ford(G,w,s)
d=2 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d=2
Return false;}
Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
i=4 Bellman-Ford algorithm

P=D
5 P=C Bellman-Ford(G,w,s)
d=2 d=4 {Initialize-single-source(G,s); //O(V)
P = NIL -2
6 B D For i=1 to (V-1) //O(V)
d=0 -3
8 -4
{ For each edge(u,v) v𝜖𝐸 //O(E)
A 2
7 Relax(u,v,w);}
Source
7 C E For each edge(u,v) v𝜖𝐸 //O(E)
P=A 9 P=B {If ((d[u]+w(u,v)) < d[v]
d=7 d = -2
Return false;}
Return True;
}
Order of Processing the Edges:
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
For each Edge Bellman-Ford algorithm
5 Bellman-Ford(G,w,s)
P=D P=C
{Initialize-single-source(G,s); //O(V)
d=2 d=4
P = NIL -2 For i=1 to (V-1) //O(V)
d=0 6 B -3
D { For each edge(u,v) v𝜖𝐸 //O(E)
8 -4
A 7 Relax(u,v,w);}
Source 2
For each edge(u,v) v𝜖𝐸 //O(E)
7 C E
P=A
{If ((d[u]+w(u,v)) < d[v]
9 P=B
d=7 d = -2 Return false;}
Return True;
}
Order of Processing the Edges: //TC=O(VE), SC=O(V+E)
(B,D), (B,C), (B,E), (D,B), (C,D), (C,E), (E,D), (E,A), (A,B), (A,C)
Bellman-Ford algorithm
Bellman-Ford(G,w,s)
{Initialize-single-source(G,s); //O(V)
For i=1 to (V-1) //O(V)
{ For each edge(u,v) v𝜖𝐸 //O(E)
Relax(u,v,w);} //O(1)
For each edge(u,v) v𝜖𝐸 //O(E)
{If ((d[u]+w(u,v)) < d[v]
Return false;}
Return True;
}
//TC = O(VE+E) = O(VE),
SC = O(2V+E) = O(V+E)
Bellman-Ford algorithm
Home Work
4 Find the shortest path from
Source A B node A to all other nodes?
5
5 -14
D C Order of Processing the Edges:
3
(C,B), (D,C), (A,D), (A,B), (D,B)
Bellman-Ford algorithm
Algorithm to print the shortest Path
Print_Path(G,s,v)
{
If v == s
Print s;
Elseif p[v] == NIL
Print “No path from source to vertex”;
Else Print_Path(G,s,p[v]);
Print v;
}
Dijkstra’s algorithm

• It computes shortest paths only for weighted digraph with


+ve weights only.
• It’s a greedy algorithm
Dijkstra’s Algorithm
1 Dijkstra(G,w,s)
{
Initialize-single-source(G,s); //O(V)
10 B D SP={empty}; //shortest path set
3 9 Min-Q=V; //O(V)
A 2 4 6
While(Min-Q is not Empty) //O(V)
Source
7 { u=dequeue(Min-Q); O(log(v))
5 SP=Union(SP,u);
C E For each adjacent vertex,v, of vertex u //O(E)
2
Relax(u,v,w); //O(1)
}
}
Dijkstra(G,w,s)
P = NIL
1 P = NIL {
d=∞ d=∞ Initialize-single-source(G,s); //O(V)
P = NIL
10 B D SP={empty}; //shortest path set
d=0
3 9 Min-Q=V; //O(V)
A 2 4 While(Min-Q is not Empty) //O(V)
Source 6 { u=dequeue(Min-Q); //O(log(v))
7
5 SP=Union(SP,u);
C E For each adjacent vertex,v, of vertex u //O(E)
2 P = NIL Relax(u,v,w); //O(1)
P = NIL
d=∞ d=∞ }
}
SP = { }
Min-Q = {A,C,B,E,D}
PP
==NIL
A
1 P = NIL Dijkstra(G,w,s)
dd == ∞
10 d=∞ {
P = NIL Initialize-single-source(G,s); //O(V)
d=0
10 B D SP={empty}; //shortest path set
3 9
A 2 4 Min-Q=V; //O(V)
Source 6 While(Min-Q is not Empty) //O(V)
7 { u=dequeue(Min-Q); //O(log(v))
5
C E SP=Union(SP,u);
2 P = NIL
For each adjacent vertex,v, of vertex u //O(E)
PP
= =NIL
A
d=∞ Relax(u,v,w); //O(1)
dd==∞5
}
SP = {A} }
{}
Min-Q
Min-Q=={A,C,B,E,D}
{C,B,E,D} If(A.d
If(A.d+ +W(A,C))
W(A,B))< <C.d
B.d
C
P=A
1 PP==NIL
C Dijkstra(G,w,s)
dd==10
8 dd== 14
∞ {
P = NIL Initialize-single-source(G,s); //O(V)
d=0
10 B D SP={empty}; //shortest path set
3 9
A 2 4 Min-Q=V; //O(V)
Source 6 While(Min-Q is not Empty) //O(V)
7 { u=dequeue(Min-Q); //O(log(v))
5
C E SP=Union(SP,u);
2 PP==NIL
For each adjacent vertex,v, of vertex u //O(E)
P=A C
d=5 dd == ∞
7
Relax(u,v,w); //O(1)
}
}
SP=={A,C}
SP {A}
Min-Q
Min-Q==={C,B,E,D}
Min-Q {B,E,D}
{E,B,D} If(C.d
If(C.d ++ W(C,E))
W(C,D)) <<E.d
D.d
If(C.d + W(C,B)) < B.d
P=C
1 P == C
P E Dijkstra(G,w,s)
d=8 13
d = 14 {
P = NIL Initialize-single-source(G,s); //O(V)
d=0
10 B D SP={empty}; //shortest path set
3 9
A 2 4 Min-Q=V; //O(V)
Source 6 While(Min-Q is not Empty) //O(V)
7 { u=dequeue(Min-Q); //O(log(v))
5
C E SP=Union(SP,u);
2 For each adjacent vertex,v, of vertex u //O(E)
P=A P=C
d=5 d=7
Relax(u,v,w); //O(1)
}
}
SP
SP== {A,C,E}
{A,C}
Min-Q
Min-Q=={E,B,D}
{B,D} If(E.d
If(E.d++W(E,D))
W(E,A))<<D.d
A.d
P=C
1 PP == E
B
Dijkstra(G,w,s)
d=8 dd==13
9 {
P = NIL Initialize-single-source(G,s); //O(V)
d=0
10 B D SP={empty}; //shortest path set
3 9
A 2 4 Min-Q=V; //O(V)
Source 6 While(Min-Q is not Empty) //O(V)
7 { u=dequeue(Min-Q); //O(log(v))
5
C E SP=Union(SP,u);
2 P=C
For each adjacent vertex,v, of vertex u //O(E)
P=A
d=5 d=7
Relax(u,v,w); //O(1)
}
SP
SP=={A,C,E,B}
{A,C,E} }

Min-Q
Min-Q=={B,D}
{D} If(B.d + W(B,C)) <
If(B.d + W(B,D)) < D.dC.d
P=C
1 P=B Dijkstra(G,w,s)
d=8 d=9 {
P = NIL Initialize-single-source(G,s); //O(V)
d=0
10 B D SP={empty}; //shortest path set
3 9
A 2 4 Min-Q=V; //O(V)
Source 6 While(Min-Q is not Empty) //O(V)
7 { u=dequeue(Min-Q); //O(log(V))
5
C E SP=Union(SP,u); //O(1)
2 P=C
For each adjacent vertex,v, of vertex u //O(E)
P=A
d=5 d=7
Relax(u,v,w); //O(log(v))
}
}
SP=={A,C,E,B}
SP {A,C,E,B,D}
Min-Q=={D}
Min-Q { } If(D.d + W(D,E)) < D.d
Dijkstra(G,w,s)
{
Initialize-single-source(G,s); //O(V)
SP={empty}; //shortest path set
Min-Q=V; //O(V)
While(Min-Q is not Empty) //O(V)
{ u=dequeue(Min-Q); //O(log(V))
SP=Union(SP,u); //O(1)
For each adjacent vertex,v, of vertex u //O(E)
Relax(u,v,w); //O(log(v))
}
}
// TC = O(Vlog(V) + Elog(V)) = O((V+E)log(V)) = O(Elog(V))
// SC = O(2V+2V) = O(V)
All Pairs Shortest Paths

• Given a weighted digraph G=(V, E), We have to find a


shortest path from vertex u to v for every pair of
vertices, u,v𝝐𝑽.
• Edge weights can be either –ve or +ve.
All Pair Shortest Paths

k
2 3

i j
8

Path = {i,j};
If (dist[i,k]+dist[k,j]) < dist[i,j])
dist[i,j] = dist[i,k]+dist[k,j]); where k = 1 to V
update the path as {i,k,j};
If (k=0),
D[i,j] = W[i,j];
2
3 4 D(k=0) = 1 2 3 4 5

1 0
8
1 3 2
3
2 4
-4 1
7 -5 5

6 Pj(k=0) = 1 2 3 4 5
5 4 1 Nil

If (i = = j) OR W[i,j] = = ∞), 2

Pj[i,j] = Nil; 3

If (i ≠ j) AND W[i,j] < ∞), 4

Pj[i,j] = i; 5
If (k=0),
D[i,j] = W[i,j];
2
3 4 D(k=0) = 1 2 3 4 5

1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 ∞ -5 0 ∞
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=0) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1

If (i = = j) OR W[i,j] = = ∞), 2 Nil Nil Nil 2 2

Pj[i,j] = Nil; 3 Nil 3 Nil Nil Nil

If (i ≠ j) AND W[i,j] < ∞), 4 4 Nil 4 Nil Nil

Pj[i,j] = i; 5 Nil Nil Nil 5 Nil


If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 ∞ -5 0 ∞
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

5
6
4 Pj(k=1) = 1 2 3 4 5

1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 Nil 4 Nil Nil
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 ∞ -5 0 ∞
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=0) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 Nil 4 Nil Nil
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 ∞ -5 0 ∞
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=0) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 Nil 4 Nil Nil
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 ∞ -5 0 ∞
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=0) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 Nil 4 Nil Nil
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 5 -5 0 ∞
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=0) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 1 4 Nil Nil
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 5 -5 0 -2
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=1) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 1 4 Nil 1
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=1) = j=1 2 3 4 5

i=1 0 3 8 ∞ -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 ∞ ∞
2 4 2 5 -5 0 -2
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=1) = 1 2 3 4 5
5 4 1 Nil 1 1 Nil 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil Nil Nil
4 4 1 4 Nil 1
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=2) = j=1 2 3 4 5

i=1 0 3 8 4 -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 5 11
2 4 2 5 -5 0 -2
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=2) = 1 2 3 4 5
5 4 1 Nil 1 1 2 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil 2 2
4 4 1 4 Nil 1
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=3) = j=1 2 3 4 5

i=1 0 3 8 4 -4
8
1 3 2 ∞ 0 ∞ 1 7
3 ∞ 4 0 5 11
2 4 2 -1 -5 0 -2
-4 1 ∞ ∞ ∞ 6 0
7 -5 5

6 Pj(k=3) = 1 2 3 4 5
5 4 1 Nil 1 1 2 1
2 Nil Nil Nil 2 2
3 Nil 3 Nil 2 2
4 4 3 4 Nil 1
5 Nil Nil Nil 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=4) = j=1 2 3 4 5

i=1 0 3 -1 4 -4
8
1 3 2 3 0 -4 1 -1
3 7 4 0 5 3
2 4 2 -1 -5 0 -2
-4 1 8 5 1 6 0
7 -5 5

6 Pj(k=4) = 1 2 3 4 5
5 4 1 Nil 1 4 2 1
2 4 Nil 4 2 1
3 4 3 Nil 2 1
4 4 3 4 Nil 1
5 4 3 4 5 Nil
If (D[i,k]+D[k,j]) < D[i,j]),
D[i,j] = D[i,k]+D[k,j]); If (k >= 1), Pj[i,j] = Pj[k,j];
2
3 4 D(k=5) = j=1 2 3 4 5

i=1 0 1 -3 2 -4
8
1 3 2 3 0 -4 1 -1
3 7 4 0 5 3
2 4 2 -1 -5 0 -2
-4 1 8 5 1 6 0
7 -5 5

6 Pj(k=5) = j=1 2 3 4 5
5 4 i=1 Nil 3 4 5 1
2 4 Nil 4 2 1
3 4 3 Nil 2 1
4 4 3 4 Nil 1
5 4 3 4 5 Nil
All Pairs Shortest Paths
Floyd-Warshall Algorithm
Floyd-Warshall(W) Time
{
// Initialization Complexity:
For i=1 to V //O(V)
For j=1 to V //O(V) =O(V2+V3)
{D[i,j] = W[i,j]; =O(V3)
If (i = = j) OR W[i,j] = = ∞) //O(1)
Pj[i,j] = Nil; //O(1)
If (i ≠ j) AND W[i,j] < ∞) //O(1) Space
Pj[i,j] = i;} //O(1)
//Computation of All Pair Shortest Path Complexity:
for k=1 to V //O(V)
for i=1 to V //O(V) =O(V2 +V2)
for j=1 to V //O(V) =O(V2)
{If (D[i,k]+D[k,j]) < D[i,j]), //O(1)
D[i,j] = D[i,k]+D[k,j]); //O(1)
If (k >= 1), Pj[i,j] = Pj[k,j]; //O(1)
}
}
Tree Data Structure

• It is primarily used to represent data with hierarchical


relationships.
• Like family tree, Organizational hierarchy, Hierarchy of
chapters and sections in a book, etc.
Book

Chap-1 Chap-2 Chap-3

Section-1.1 Section-1.2 Section-1.3

Sub-section-1.1.1 Sub-section-1.1.2 Sub-section-1.1.3


Tree Data Structure

• Tree is an acyclic graph or sub-graph.


• If one of its node is designated as root node, then its called
a rooted tree.
• Set of disjoint trees is called Forest.
• A node of a tree can be connected by single edges to zero or
more nodes(children nodes) at its immediate lower level.
• Leaf node is a terminal node without any child node.
Tree Data Structure

• Degree/Order of a node is equal to number of its children


nodes.
• A parent node of a given node, V, is the node to which
node, V, is connect with an edge at its immediate upper
level.
Root Node
A
Parent
Node
B C
Child Node
D E F G

Sibling
Nodes
Root Node Right Sub-
Left Sub- A Tree
Tree

B C

D E F G
For a Rooted Tree,T, with root, r:

• Depth of a vertex, v:
• Depth(v)=length of path from root, r, to vertex, v.
• Height of a vertex, v:
• Height(v)=length of the longest path from vertex, v, to
a leaf.
• Depth of the Tree,T:
• Depth(T)=Depth of the deepest vertex.
• Height of the Tree, T:
• Height(T)=Height( r );
For a Rooted Tree,T, with root, r:
• Level of a vertex, v:
• Level(v)=Height(T) – Depth(v)
Depth=0 Height=2
Book
Depth=1
Height=1
Chap-1 Chap-2 Chap-3

Depth=2 Height=0
Section-1.1 Section-1.2
Level=2
Book

Level=1

Chap-1 Chap-2 Chap-3

Level=0
Section-1.1 Section-1.2
A
B
C

• Maximum height of a tree with ‘n’ vertices = (n-1)


• Maximum depth of a tree with ‘n’ vertices = (n-1)
Binary Tree
• Its a tree in which each node can have either 0, 1 or 2 child
nodes.
A

B C

D E G
Ternary Tree
• Its a tree in which each node can have either 0, 1, 2 or 3
child nodes.
A

B C

D E F G
m-ary Tree
• Its a tree in which each node can have either 0,1,2,3…m
child nodes.

B C

D E .............. . Z G
Full m-ary Tree
• Its a m-ary tree in which each non-leaf/internal node has
exactly m child nodes.
• If m=2, then it’s a full binary tree
A

B C

D E
• For a Full m-ary tree, T, with ‘n’ nodes:
• Height(T) = floor(logm(n)).

• If m=2; Height(T)=floor(log2(5)) = floor(2.32) = 2


A Level=2

B C Level=1

D E Level=0
• For a Full m-ary tree, T, with ‘n’ nodes:
(𝑛−1)Τ
• No. of internal vertices, i, = 𝑚
𝑚−1 𝑛+1Τ
• No. of leaf nodes, L, = 𝑚
• No. of nodes, n, = mi+1
• L=(mi-1)+1
(𝑚𝐿−1)
• n= ൗ(𝑚−1)
(𝐿−1)
• i= ൗ(𝑚−1)
Complete m-ary Tree
• Its a m-ary tree in which each depth is filled from left to
right and the next depth can only be filled when the current
depth is completely filled.
• If m=2, then its complete binary tree
A Level=2

C Level=1
B

D E F Level=0
Full and Complete m-ary Tree

• If m=2, then it’s full and complete binary tree

A Level=2

C Level=1
B

D E F G Level=0
Balanced m-ary Tree
• Its a m-ary tree in which all the leaf nodes are at level 0 0r
1.
• If m=2, then its balanced binary tree
A Level=2

C Level=1
B

D E Level=0
• For a full & complete m-ary tree, T, with ‘n’ nodes:
• Height(T) = floor(logm(n)).

• If m=2; Height(T)=floor(log2(7)) = floor(2.807) = 2


A Level=2

B C Level=1

D E F G Level=0
• For a full & complete m-ary tree, T, with height ‘h’:
• No. of leaf nodes = mh.

• If m=2; No. of leaf nodes = 22=4


A Level=2

B C Level=1

D E F G Level=0
• For a full & complete m-ary tree:
• The number of nodes(NN) at level, L, = m(Height(T) - L).
• The number of nodes at Depth, D, = m(D).
• If m=2;
Level=2 A NN=2(2-2)=1

Level=1 NN=2(2-1)=2
B C
Level=0
D E F G NN=2(2-0)=4
Tree Data Structure
Set of Values:
• Domain Specific.

Set of Operations:
1. Insert
2. Delete
3. Search/Traversals
Implementation
1. Array
2. Linked List
Binary Tree

Implementation
1. Array
2. Linked List
Array implementation of Binary Tree
Root, i = 1 A
Left Child =2i
Right Child =2i+1
Parent =i/2 B C

D E F G

0 1 2 3 4 5 6 7
A B C D E F G
Array implementation of Binary Tree
Root, i = 1
Left Child =2i A
Right Child =2i+1
Parent =i/2
B C

D G

0 1 2 3 4 5 6 7
A B C D G
Linked List implementation of Binary Tree

Data A
LPtr RPtr

B C
A

B C
Null Null Null Null
Tree Traversals

Stack based Queue based


1. Pre-order Traversal 1. Level Order Traversal
2. In-order Traversal
3. Post-order Traversal
1. Pre-Order Tree Traversal
1. Visit Root node
2. Visit Left Child/Sub-Tree
3. Visit Right Child/Sub-Tree
A

B C

Pre-Order Traversal: A B C
1. Pre-Order Tree Traversal
1. Visit Root node
A
2. Visit Left Child/Sub-Tree
3. Visit Right Child/Sub-Tree
B C

D E F G

Pre-Order Traversal: A B D E C F G
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data;
If(ptr->right ≠ Null) D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Else Pre-Order Traversal:
Ptr = Pop(S) ptr = 1
}
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data);
If(ptr->right ≠ Null) 3 D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
Ptr = Pop(S) ptr
ptr==12 A
}
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data; 5
If(ptr->right ≠ Null) 3 D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
ptr = 2
Ptr = Pop(S) A B
} ptr = 4
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data; 5
If(ptr->right ≠ Null) 3 D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
ptr = 4
Ptr = Pop(S) A B D
} ptr = 5
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data;
If(ptr->right ≠ Null) 3 D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
ptr = 5
Ptr = Pop(S) A B D E
} ptr = 3
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data;
If(ptr->right ≠ Null) 7 D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
ptr = 3
Ptr = Pop(S) A B D E C
} ptr = 6
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data;
If(ptr->right ≠ Null) 7 D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
ptr = 6
Ptr = Pop(S) A B D E C F
} ptr = 7
Non-Recursive Pre-Order Tree Traversal using Stack
CreateEmptyStack(S); Root A 1
Push(S,Null);
ptr = Root;
While (ptr ≠ Null) B 2 C 3
{ print(ptr->data);
If(ptr->right ≠ Null) D E F G
Push(S,ptr->right); Null 4 5 6 7
If(ptr->left ≠ Null)
Ptr = ptr->left; Stack, S
Pre-Order Traversal:
Else
ptr = 7
Ptr = Pop(S) A B D E C F G
} ptr = Null
Recursive Pre-Order Tree Traversal
Root A 1

Void PreOrder(node root) B 2 C 3


{if(root ≠ null) F G
D E
Print(root->data);
4 5 6 7
PreOrder(root->left);
PreOrder(root->right);
}
2. In-Order Tree Traversal
1. Visit Left Child/Sub-Tree
2. Visit Root node
3. Visit Right Child/Sub-Tree A

B C

In-Order Traversal: B A C
2. In-Order Tree Traversal

A
1. Visit Left Child/Sub-Tree
2. Visit Root node B C
3. Visit Right Child/Sub-Tree
D E F G

In-Order Traversal: D B E A F C G
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
4
} B C
ptr = Pop(S);
2
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
1
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 1
If( ptr = = Null)
Done = true; D
} ptr = 4
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
2
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
1
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr==54
ptr
If( ptr = = Null)
Done = true; D B
} ptr = 2
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S); 5
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
1
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 5
If( ptr = = Null)
Done = true; D B
} ptr = Null
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S); 5
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
1
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = Null
If( ptr = = Null)
Done = true; D B E
} ptr = 5
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
1
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 5
If( ptr = = Null)
Done = true; D B E
} ptr = 1
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data); 4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 1
If( ptr = = Null)
Done = true; D B E A
} ptr = 3
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
3
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 3
If( ptr = = Null)
Done = true; D B E A
} ptr = 6
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S); 6
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
3
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 6
If( ptr = = Null)
Done = true; D B E A
} ptr = 6
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
3
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 6
If( ptr = = Null)
Done = true; D B E A F C
} ptr = 3
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
7
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 3
If( ptr = = Null)
Done = true; D B E A F C
} ptr = 7
CreateEmptyStack(S);
Push(S,Null);
Non-Recursive In-Order
Ptr=Root;
Done=false;
Tree Traversal
While(done == false)
{While(ptr ≠ null) Root A 1
{Push(S, ptr);
ptr = ptr->left; 2 3
} B C
ptr = Pop(S);
flag = true;
D E F G
While( (ptr ≠ null) and (flag ==true))
{ print(ptr->data);
7
4 5 6 7
if(ptr->right ≠ null)
{ ptr = ptr->right;
Null
flag = false;
} Stack, S
else
ptr = Pop(S);
In-Order Traversal:
} ptr = 7
If( ptr = = Null)
Done = true; D B E A F C G
} ptr = Null
Recursive In-Order Tree Traversal

Void InOrder(Root)
{
If(Root ≠ Null)
Root A 1
{
2
InOrder(Root->left); C
3
B
Print(Root->data);
InOrder(Right->right); D E F G
4
} 5 6 7

}
3. Post-Order Tree Traversal

A
1. Visit Left Child/Sub-Tree
2. Visit Right Child/Sub-Tree B C
3. Visit Root node
D E F G

Post-Order Traversal: D E B F G C A
Non-Recursive Post-Order Tree Traversal using Stack
//Initialization //Traversal //Printing
CreateEmptyStack(S1); S1.Push1(ptr); ptr = S2.Pop2( );
CreateEmptyStack(S2); ptr = S1.Pop1( ); While(ptr ≠ Null)
Char flag; While(ptr ≠ Null) {
S1.Push1(Null); {S2.Push2(ptr); Print(ptr->data);
S2.Push2(Null); if(ptr->left ≠ Null) ptr = S2.Pop2( );
Ptr=root; S1.Push1(ptr->left); }
if(ptr->right ≠ Null)
S1.Push1(ptr->right);
ptr = S1.Pop1( );
}
}
Non-Recursive Post-Order Tree Traversal using Stack
//Initialization Root A 1
CreateEmptyStack(S1);
CreateEmptyStack(S2);
Char flag;
B 2 C 3
S1.Push1(Null);
S2.Push2(Null); D E F G
Ptr=root; Null 4 5 6 7
Null

S1 S2

ptr = 1
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) F G
D E
S1.Push1(ptr->left); 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 1
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) F G
1 D E
S1.Push1(ptr->left);
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 1
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 3
D E F G
S1.Push1(ptr->left); 2 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 1
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) F G
1 D E
S1.Push1(ptr->left); 2
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 3
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null)
3
D E F G
S1.Push1(ptr->left); 2 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 3
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) 7 B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 6 3
D E F G
S1.Push1(ptr->left); 2 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 3
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 6 3
D E F G
S1.Push1(ptr->left); 2 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 7
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) 7 B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 6 3
D E F G
S1.Push1(ptr->left); 2 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 7
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) 7 B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null)
3
D E F G
S1.Push1(ptr->left); 2 1
if(ptr->right ≠ Null) Null Null 4 5 6 7
S1.Push1(ptr->right);
ptr = S1.Pop1( ); S1 S2
}
} ptr = 6
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 6 F G
D E
S1.Push1(ptr->left); 7
if(ptr->right ≠ Null) 4 5 6 7
S1.Push1(ptr->right); 3
ptr = S1.Pop1( ); 2 1
} Null Null ptr = 6
}
S1 S2
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 2
6 D E F G
S1.Push1(ptr->left);
if(ptr->right ≠ Null) 7 4 5 6 7
S1.Push1(ptr->right); 3
ptr = S1.Pop1( ); 1
} Null Null ptr = 2
}
S1 S2
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null) B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 2
6 D E F G
S1.Push1(ptr->left);
if(ptr->right ≠ Null) 7 4 5 6 7
S1.Push1(ptr->right);
5 3
ptr = S1.Pop1( ); 4 1
} Null Null ptr = 2
}
S1 S2
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
While(ptr ≠ Null)
5
B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 2
6 D E F G
S1.Push1(ptr->left);
if(ptr->right ≠ Null) 7 4 5 6 7
S1.Push1(ptr->right); 3
ptr = S1.Pop1( ); 4 1
} Null Null ptr = 5
}
S1 S2
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
4
While(ptr ≠ Null)
5
B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 2
6 D E F G
S1.Push1(ptr->left);
if(ptr->right ≠ Null) 7 4 5 6 7
S1.Push1(ptr->right); 3
ptr = S1.Pop1( ); 1
} Null Null ptr = 4
}
S1 S2
Non-Recursive Post-Order Tree Traversal using Stack
//Traversal Root A 1
S1.Push1(ptr);
ptr = S1.Pop1( );
4
While(ptr ≠ Null)
5
B 2 C 3
{S2.Push2(ptr);
if(ptr->left ≠ Null) 2
6 D E F G
S1.Push1(ptr->left);
if(ptr->right ≠ Null) 7 4 5 6 7
S1.Push1(ptr->right); 3
ptr = S1.Pop1( ); 1
} Null
} ptr = Null
S1 S2
Non-Recursive Post-Order Tree Traversal using Stack
//Printing 4 Root A 1
ptr = S2.Pop2( ); 5
While(ptr ≠ Null)
{
2
B 2 C 3
6
Print(ptr->data); 7
ptr = S2.Pop2( ); D E F G
3
} 1 4 5 6 7
Null

ptr = 4 S1 S2 Post-Order Traversal:

D
A E B F G C A
Recursive Post-Order Tree Traversal

Void PostOrder(node root)


{
if(root ≠ Null)
{
PostOrder(root->left);
PostOrder(root->right);
Print(root->data);
}
}
Level Order Tree Traversal
1
Void LevelOrder(node root) Root A
{ CreateEmptyQ(Q); 3
2
ptr = root;
Enqueue(ptr); B C
While(ptr ≠ Null)
{ptr = Dequeue( ); D E F G
Print(ptr->data);
4 5 6 7
Enqueue(ptr->left);
Enqueue(ptr->right);
}
}
Expression Tree
1
-
A
• They are used to represent Algebraic
2 3
Expressions.
*
B /
C
• Ex. A*B-C/D C
F D
G
A
D B
E
4 5 6 7
Expression Tree
ExpressionTree(infix) if(symbol == Operator)
{ Obtain the Postfix Expression, PE; {ptr = create a new node;
Append ‘#’ to PE; ptr->data = PE[i];
CreatEmptyStack(S); ptr->right = Pop(S);
i=1; symbol = PE[i]; ptr->left = Pop(S);
While( symbol ≠ ‘#’) Push(S,ptr);
{ if(symbol == Operand) }
{ ptr = create a new node; i++;
ptr->data = PE[i]; Symbol=PE[i];
ptr->left = Null; }
ptr->right = Null;
Push( S, ptr);
}
Infix Expression: A*B-C/D Expression Tree
Postfix Expression: AB*CD/-#

Stack

A B
*

A B
Infix Expression: A*B-C/D Expression Tree
Postfix Expression: AB*CD/-#
Stack

* C D

A B
Infix Expression: A*B-C/D Expression Tree
Postfix Expression: AB*CD/-#
Stack

* C D
/
A B C D
Infix Expression: A*B-C/D Expression Tree
Postfix Expression: AB*CD/-#
Stack

* / -

A B C D
* /

A B C D
Stack
Expression Tree

• Pre-Order Traversal gives Pre-fix Expression.


- • In-Order Traversal gives Infix Expression.
• Post-Order Traversal gives Postfix Expression.
* /

A B C D
Stack Evaluation of Expression Tree
EvaluateExpressionTree(root)
{ if(root->data == Operand)
- return (Operand);
else
* / { operator = root->data;
R1=EvaluateExpressionTree(root->left);
A B C D R2=EvaluateExpressionTree(root->right);
root->data =Operation(R1,R2,operator);
}
}
Binary Search Tree (BST)
It is a Binary Tree in which the following conditions hold:

• The value of the left child node is always less than the
value of its parent node.
• The value of the right child node is always greater than or
equal to the value of its parent node.
• The left and right subtree are also BSTs.
Binary Search Tree (BST)
50

40 60

2 45 55 65

• Time required for Insertion, Deletion & Search is O(h),


where h=height of BST.
• In-Order Traversal sorts the data in ascending order.
Inserting a data element into a BST
While(ptr2 ≠ Null)
Insert(root, data)
{ if(ptr2->data < data)
{ptr1 = Create new node;
{if(ptr2->left == Null)
ptr1->data=data;
{ptr2->left = ptr1;
ptr1->left=Null;
return;}
ptr1->right=Null;
else ptr2=ptr2->left;}
if(root == Null)
else
{root = ptr1;
{if(ptr2->right == Null)
return;}
{ptr2->right = ptr1;
ptr2 = root;
return;}
else ptr2 = ptr2->right;}
}}
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50
60
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50
60

55
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50

20 60

55
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50
60
20

45 55
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50
60
20

45 55

40
Inserting a data element into a BST
50,60,55,20,45,40,65
Root
50
60
20

45 55 65

40
Deleting a node from a BST
• Three Cases
1. deleting a leaf node
2. deleting an intermediate node with one
child/subtree
3. deleting an intermediate node with both
children/subtree
Deleting a node from a BST
1. deleting a leaf node
Find the Parent
Root
50
10 20
60

10 45 55 65

40
2. deleting an intermediate node with one child/subtree
2.1. intermediate node with left child/subtree only.
Find the Parent
Root
50

45 45
60

20 55 65

10
40
2. deleting an intermediate node with one child/subtree
2.2. intermediate node with right child/subtree only.
Find the Parent
Root
50

10 10
60

40 55 65

20
45
3. deleting an intermediate node with both child/subtree
• Find the Inorder
60 50 Successor(IOS) of 60.
• Find the parent of the IOS.
40 60
• If IOS is a leaf node
62

55 75

88
65

62
62 69
3. deleting an intermediate node with both child/subtree
• Find the Inorder
45 Successor(IOS) of 40.
58 • Find the parent of the IOS.
• If IOS is an intermediate node
40 60

22 45
45
48
55 65

42 48
48

50

49
55
Algorithm for node deletion from BST

Deletenode(root, int data)


{ node *ptr,*parent,*X,*Xparent;
ptr = root;
if(root == Null)
{print(“BST is Empty”);
Return;}
Algorithm for node deletion from BST
Else
{parent = ptr;
//Search for the node to be deleted
while(ptr ≠ Null)
{if(ptr->data == data)
break;
if(ptr->data > data)
{parent = ptr;
ptr = ptr->right;}
if(ptr->data < data)
{parent = ptr;
ptr = ptr->left;}
} //End of Search
Algorithm for node deletion from BST
if(ptr == Null)
{print(“Data not found in BST”);
return(Null);}
else
{//case-1: node is a leaf node
if(ptr->left==Null and ptr->right==Null)
{if(ptr == root)
{root = Null; free(ptr)}
else
{if(parent->left==ptr)
parent->left=Null;
else
parent->right=Null;
}
Algorithm for node deletion from BST

{//case-2: node is an intermediate node with one subtree


//case-2.1: intermediate node with only left subtree
if(ptr->left ≠ Null and ptr->right == Null)
{if(ptr == root)
{root = ptr->left; free(ptr);}
else
{if(parent->left == ptr)
parent->left = ptr->left;
else
parent->right = ptr->left;
}
Algorithm for node deletion from BST

{//case-2: node is an intermediate node with one subtree


//case-2.2: intermediate node with only right subtree
if(ptr->right ≠ Null and ptr->left == Null)
{if(ptr == root)
{root = ptr->right; free(ptr);}
else
{if(parent->left == ptr)
parent->left = ptr->right;
else
parent->right = ptr->right;
}
Algorithm for node deletion from BST
{//case-3: intermediate node with both subtrees
if(ptr->right ≠ Null and ptr->left ≠ Null)
{ X = ptr->right; //IOS
Xparent = ptr; //Parent of IOS
//find the in-order successor(IOS)
While(1)
{if(X->left ≠ Null)
{Xparent = X;
X = X->left;
continue;}
else break;
}
Algorithm for node deletion from BST

//if IOS is a leaf node


if((X->left == Null) AND (X->right == Null))
{ptr->data = X->data;
Xparent->left = Null;
free(X);}
//if IOS is an intermediate node
if((X->left == Null) AND (X->right ≠ Null))
{ptr->data = X->data;
Xparent->left = X->right;
free(X);}
}}
}
Skewed Binary Search Trees
22
40

15
45

7 48

6 50

4 55

• Time Complexity for BST Operations is O(n), which is not


desirable.
• We need it to be O(log2(n)).
Balanced Trees

• Let, Left Sub Tree of a Tree, T, be denoted as LST.


• Let, Right Sub Tree of a Tree, T, be denoted as RST.
• Balance Factor(BF) = height(LST) – height(RST).
• For a balanced tree, its BF = 0.
• For a Balanced Tree, its each sub-tree/node is also
balanced.
• Height of Balanced Tree is log(n).
• Time complexity of the operations of Balanced Tree is
O(log(n)).
Balanced Trees
BF = (2-2)=0
48

BF = (1-1)=0 BF = (1-1)=0
40 60

BF = (0-0)=0 BF = (0-0)=0 BF = (0-0)=0


BF = (0-0)=0
22 45 55 65

A Balanced BST
AVL Trees
• An AVL Tree is a BST, with Balance Factor as -1, 0 or 1.
48
BF = (1-2) = -1 BF = (2-2) = 0
48

40 60 40 60

22 45
65 65
55 55

48 BF = (2-1) = 1

40 60

22 45
AVL Trees
• Insertion and Deletion Operations on AVL Trees can make
it unbalanced.
• When an AVL Tree is not balanced, rotation operations are
carried out to balance it.
• Types of Rotations:
• Single Rotations
• Right (RR) rotation
• Left (LL) rotation
• Double Rotations
• Left-Right (LR) rotation
• Right-Left (RL) rotation
• Right rotation
2 10
58

21 0 0
40 60

10
22
0
15

The BST is Unbalanced


• Right rotation
2
58

2 0
40
40 60

1
22
0 If the Tree is Unbalanced then
15
Identify the Nearest Ancestor (with (BF ≠ -1, 0, 1) AND
(BF >1)) of the most recently inserted Node.

Rotate the sub-tree towards Right about NA.


• Right rotation • Right Rotation is performed when a
node is inserted as Left Child.
1
58

0 0
22 60

0 0
15
40

The BST is balanced


• Left rotation
If the Tree is Unbalanced then
Identify the Nearest Ancestor (with (BF ≠ -1, 0, 1) AND
-1-2 (BF < -1)) of the most recently inserted Node.
58

-10
60

0
74

BST is Unbalanced
• Left rotation • Rotate the sub-tree towards Left
at the position of NA.
-2
58

-1
60

0
74

The BST is Unbalanced


• Left rotation • Rotate the sub-tree towards Left at
the position of NA.
-2
0

60
0
0
-1 • Left Rotation is performed when a
58
74 node is inserted as Right Child.

The BST is Balanced


• Left-Right (LR) rotation

-1-2 If the Tree is Unbalanced then


58 Identify the Nearest Ancestor
01 (with BF ≠ -1, 0, 1) of the most
60 recently inserted Node.
0
59

The BST is Unbalanced


• Left-Right (LR) rotation
1. R:
-2 Right rotate about the Parent
58
Node (60) of the most recently
1 inserted Node (59).
60

0
59

The BST is Unbalanced


• Left-Right (LR) rotation
1. R:
-2 Right rotate about the Parent
58
Node (60) of the most recently
1
inserted Node (59).
59

0 2. L:
60 Left rotate about the Nearest
Ancestor (58) of the most
The BST is Unbalanced recently inserted Node (59).
• Left-Right (LR) rotation
1. R:
0 Right rotate about the Parent
59
Node (60) of the most recently
0 0
inserted Node (59).
58 60

2. L:
Left rotate about the Nearest
Ancestor (58) of the most
The BST is Balanced recently inserted Node (59).
• Right-Left (RL) rotation
21 If the Tree is Unbalanced then
74
Identify the Nearest Ancestor
74
(with BF ≠ -1, 0, 1) of the most
01
recently inserted Node.
60

0
65

The BST is Unbalanced


• Right-Left (RL) rotation
2
1. L:
74
Left rotate about the Parent
1 Node (60) of the most recently
60 inserted Node (65).
0
65

The BST is Unbalanced


• Right-Left (RL) rotation
2
1. L:
74
Left rotate about the Parent
1 Node (60) of the most recently
65 inserted Node (65).
0
2. R:
60
Right rotate about the Nearest
Ancestor (74) of the most
The BST is Unbalanced recently inserted Node (65).
• Right-Left (RL) rotation
1
1. L:
65
Left rotate about the Parent
0 0 Node (60) of the most recently
60 74 inserted Node (65).
2. R:
Right rotate about the Nearest
Ancestor (74) of the most
The BST is Balanced recently inserted Node (65).
AVL Trees

• Deletion can also cause a Tree to become Unbalanced.


• Accordingly, one or more rotations have to be performed
to obtain a balanced tree.
• Delete 45
2
1
40
40
0
0 0
45 30
30
0 0
0 0 20
35
20
35

Balanced BST Unbalanced BST


• Delete 45
2 Identify the Node with
40
BF ≠ -1,0,1.
0
If its Child Node’s BF = 0,1
30
Then Do Single Rotation
0 0 about its Parent Node.
20
35

Unbalanced BST
• Delete 45
2
-1
40
30
0
0 1
30
40
20
0 0
20
0
35
35

Unbalanced BST Balanced BST


• Delete 55
2
1
40
40
1
1 0
55 30
30
0
0
20
20

Balanced BST Unbalanced BST


• Delete 55
2 Identify the Node with
40
BF ≠ -1,0,1.
1
If its Child Node’s BF = 0,1
30
Then Do Single Rotation
0 about its Parent Node.
20

Unbalanced BST
• Delete 55
2
0
40
30
1
0 0
30
40
20
0
20

Unbalanced BST Balanced BST


Deleting 60
1 2
58 58
-1 1 -1 0
40 60 40 59
0 0 0 0
22 45 0 22 45
0 59 0 0
42 48 42
0 48

Balanced BST Unbalanced BST


Deleting 60 Identify the Node with
BF ≠ -1,0,1.
2
58
If its Child Node’s BF = -1
-1 0 Then Do one/more Single
40 59
0 0
Rotations.
22 45
0
0
42 48

Unbalanced BST
Deleting 60 Do First Single Rotation about
the Child Node with BF = -1.
2
58 2
58
-1 0
40 59 1 0
0 0 45 59

22 45 0 0
0 40 48
0
42 0 0
48
22 42

Unbalanced BST Unbalanced BST


Deleting 60 Do Second Single Rotation about the
Node with BF ≠ -1,0,1.
2
58 0
1 0 45
1 0
45 59
40 58
0 0
0 0 0 0
40 48
22 42 48 59
0 0
22 42
Balanced BST
Unbalanced BST
Multi-Way Search Trees
Pointer Pointer
to LST Data to RST

BST node Structure

• For BST,
• Number of pointers, m = 2.
• Number of data/key = (2-1) = 1.
Multi-Way Search Trees
Pointer Pointer
to LST Data to RST P0 D0/K0 P1
BST node Structure

• For BST,
• Number of pointers(order), m = 2.
• Number of data/key = (2-1) = 1.
Multi-Way Search Trees

P1 K1 P2 K2 P3 K3 P4 K4 P5
Node Structure of M-Way Search Tree
• Number of pointers, m = 5.
• Number of data/key = (m-1)= (5-1) = 4.
• K1< K2 < K3 < K4
Multi-Way Search Trees

P1 K1 P2 K2 P3 K3 P4 K4 P5
Node Structure of M-Way Search Tree
• Key Values pointed to by P1 is less than K1
• Key Values pointed to by P2 is less than K2
• Key Values pointed to by P3 is less than K3
• Key Values pointed to by P4 is less than K4
Multi-Way Search Trees

P1 K1 P2 K2 P3 K3 P4 K4 P5
Node Structure of M-Way Search Tree
• Key Values pointed to by P2 is greater than K1
• Key Values pointed to by P3 is greater than K2
• Key Values pointed to by P4 is greater than K3
• Key Values pointed to by P5 is greater than K4
Multi-Way Search Trees

P1 K1 P2 K2 P3 K3 P4 K4 P5
Node Structure of M-Way Search Tree

• Every sub-tree of an M-Way Search Tree is also a M-


Way Search Tree.
Multi-Way Search Trees
• Order, m=3
P1 60 P2 85 P3

P11 20 P12 30 P13 # 64 # 75 P23 # 90 P32 135 #

# 6 # 8 # # 32 # 45 # # 99 # 112 #

# 22 # 25 #
# 78 # 80 #
Multi-Way Search Trees
• Order, m=3 P1 60 P2 85 P3

P11 20 # 30 #

P111 16 # 18 #

# 6 # 8 #

A Deep m-way search tree (Undesirable)


Balanced Search Trees (B-Trees)
• Balanced M-Way Search Tree is called B-Tree.

• B-Tree has the following properties:


1. Its root has at least two child nodes and at most m
child nodes.
2. Internal nodes have at least ceil(m/2) child nodes
and at most m child nodes.
3. All leaf nodes are on the same level.
• Order, m = 4 B-Trees

P1 45 P2

P11 29 P12 32 P13 P21 49 P22 63 P23

# 18 # 27 # # 36 # 39 # # 46 # 47 P23 # 67 # 72 #

# 30 # 31 #
# 54 # 59 # 61 #
• Order, m = 4 B-Trees
• Searching,
31, 61, 18 P1 45 P2

P11 29 P12 32 P13 P21 49 P22 63 P23

# 18 # 27 # # 36 # 39 # # 46 # 47 P23 # 67 # 72 #

# 30 # 31 #
# 54 # 59 # 61 #
• Inserting an Element:
B-Trees
• All insertions takes place at leaf nodes.
• Procedure:
1. Find the leaf node to insert the data.
2. If the leaf node is not full, then insert the data at appropriate
location in the leaf node.
3. If the leaf node is full, then
4. Arrange the data of the above node in ascending order and
find its median.
5. Push the median data into it’s parent node and split the node
into two nodes.
6. If the parent node is full, then go to step-4.
• Order, m = 5 B-Trees
p1 18 p2 45 p3 72 p4 # #

# 7 # 11 # # # # #

# 21 # 27 # 36 # 42 #

# 54 # 63 # # # # #

# 81 # 89 # 90 # # #

• Inserting, 8, 9, 39, 4
• Order, m = 5 B-Trees
p1 18 p2 45 p3 72 p4 # #

# 7 # 8 # 11 # # #

# 21 # 27 # 36 # 42 #

# 54 # 63 # # # # #

# 81 # 89 # 90 # # #

• Inserting, 8, 9, 39, 4
• Order, m = 5 B-Trees
p1 18 p2 45 p3 72 p4 # #

# 7 # 8 # 9 # 11 #

# 21 # 27 # 36 # 42 #

# 54 # 63 # # # # #

• Inserting, 8, 9, 39, 4 # 81 # 89 # 90 # # #

• Node is Full, So
• Arrange the data in ascending order, 21,27,36,39,42
• Median = 36
• Order, m = 5 B-Trees
p1 18 p2 36 p3 45 p4 72 p5

# 7 # 8 # 9 # 11 #

# 21 # 27 # # # # #

# 39 # 42 # # # # #

# 54 # 63 # # # # #

# 81 # 89 # 90 # # #
• Inserting, 8, 9, 39, 4
• Order, m = 5 B-Trees
p1 18 p2 36 p3 45 p4 72 p5

# 7 # 8 # 9 # 11 #


# 21 # 27 # # # # #
Node is Full, So
• Arrange the
# data
39 # in42 ascending
# # # # order,
# 4,7,8,9,11
• Median = 8, Push into parent and split the node
# 63

54 # # # # # #
Parent node is also full
• Arrange the data in ascending# order, 81 #
8,18,36,45,72
89 # 90 # # #
•• Inserting,
Median 8, 9,push
= 36, 39, 4into parent and split the node
• Order, m = 5 B-Trees
p1 36 p2 # # # # # #

p11 8 p12 18 p13 # # # # p21 45 p22 72 p23 # # # #

# 39 # 42 # # # # #
# 4 # 7 # # # # #
# 54 # 63 # # # # #
# 9 # 11 # # # # #
# 81 # 89 # 90 # # #
# 21 # 27 # # # # #

• Inserting, 8, 9, 39, 4
B-Trees
• Deleting an Element:
• All deletions takes place at leaf nodes.
• Procedure:
1. Find the leaf node to delete the data.
2. If the leaf node contains more than [ceil(m/2)-1] data, then
delete the data from the appropriate location in the leaf node.
3. Else-If the leaf node contains less than [ceil(m/2)-1] data,
then,
(i). If the left sibling has more than [ceil(m/2)-1] data, then
push its largest element into its parent node and pull down
the intervening data from the parent node to the leaf node.
B-Trees
(ii). Else-If the right sibling has more than [ceil(m/2)-1]
data, then push its smallest element into its parent node and
pull down the intervening data from the parent node to the
leaf node.
4. Else-If, both left and right siblings contain exactly [ceil(m/2)-
1] then create a new leaf node by combining them with the
intervening data of the parent node.
5. If pulling the intervening data from the parent node leaves it
with less than [ceil(m/2)-1] data, then propagate the process
upwards.
B-Trees
6. To delete an data in an internal node, promote the successor or
predecessor of the data to occupy the position of the deleted data.
• Order, m = 5 B-Trees
p1 108 p2 # # # # # #

p11 63 p12 81 p13 # # # # p21 117 p22 201 p23 # # # #

# 111 # 114 # # # # #
# 36 # 45 # # # # #
# 151 # 180 # # # # #
# 72 # 79 # # # # #
# 243 # 256 # 333 # 450 #
# 90 # 93 # 101 # # #

• Deleting, 93
• Order, m = 5 B-Trees
p1 108 p2 # # # # # #

p11 63 p12 81 p13 # # # # p21 117 p22 201 p23 # # # #

# 111 # 114 # # # # #
# 36 # 45 # # # # #
# 151 # 180 # # # # #
# 72 # 79 # # # # #
# 243 # 256 # 333 # 450 #
# 90 # 101 # # # # #

• Deleting, 93, 201


• Order, m = 5 B-Trees
p1 108 p2 # # # # # #

p11 63 p12 81 p13 # # # # p21 117 p22 243 p23 # # # #

# 111 # 114 # # # # #
# 36 # 45 # # # # #
# 151 # 180 # # # # #
# 72 # 79 # # # # #
# 256 # 333 # 450 # # #
# 90 # 101 # # # # #

• Deleting, 93, 201, 180


• Order, m = 5 B-Trees
p1 108 p2 # # # # # #

p11 63 p12 81 p13 # # # # p21 117 p22 256 p23 # # # #

# 111 # 114 # # # # #
# 36 # 45 # # # # #
# 151 # 243 # # # # #
# 72 # 79 # # # # #
# 333 # 450 # # # # #
# 90 # 101 # # # # #

• Deleting, 93, 201, 180, 72


• Order, m = 5 B-Trees
p1 81 p2 108 p3 117 p4 256 p5

# 36 # 45 # 63 # 79 # # 151 # 243 # # # # #

# 90 # 101 # # # # # # 333 # 450 # # # # #

# 111 # 114 # # # # #

• Deleting, 93, 201, 180, 72,


B+ Trees

• It is a variant of B-Tree that stores index values in the


intermediate nodes and data in the leaf nodes.
• Also, all the leaf nodes are linked using single or double linked
list.
B+ Trees
• Example: p1 25 p2 # # # # # #

# 5 # 10 # 15 # 20 p11 p21 25 # 55 # 60 # 65 #
• Insertion B+ Trees
• Order, m = 5 p1 25 p2 50 p3 75 p4 # #

# 5 # 10 # 15 # 20 # # 50 # 55 # 60 # 65 #

# 25 # 30 # # # # # # 75 # 80 # # # # #

• Insert 28
• Order, m = 5 B+ Trees
p1 25 p2 50 p3 75 p4 # #

# 5 # 10 # 15 # 20 # # 50 # 55 # 60 # 65 #

# 25 # 28 # 30 # # # # 75 # 80 # # # # #

• Insert 28, 70
• Order, m = 5 B+ Trees
p1 25 p2 50 p3 60 p4 75 p5

# 5 # 10 # 15 # 20 # # 50 # 55 # 60 # 65 #

# 25 # 28 # 30 # # # # 60 # 65 # 70 # # #

# 75 # 80 # # # # #

• Insert 28, 70
• Deletion B+ Trees
• Order, m = 5
p1 17 p2 # # # # # #

p11 5 p12 13 p13 # # # # p21 24 p22 30 p23 # # # #

# 19 # 20 # 22 # # #
# 2 # 3 # # # # #
# 24 # 27 # 29 # # #
# 5 # 7 # 8 # # #
# 30 # 33 # 34 # 39 #
# 13 # 16 # # # # #

• Deleting, 19
• Deletion B+ Trees
• Order, m = 5
p1 17 p2 # # # # # #

p11 5 p12 13 p13 # # # # p21 24 p22 30 p23 # # # #

# 19 # 20 # 22 # # #
# 2 # 3 # # # # #
# 24 # 27 # 29 # # #
# 5 # 7 # 8 # # #
# 30 # 33 # 34 # 39 #
# 13 # 16 # # # # #

• Deleting, 19, 20
• Deletion B+ Trees
• Order, m = 5
p1 17 p2 # # # # # #

p11 5 p12 13 p13 # # # # p21 27 p22 30 p23 # # # #

# 22 # 24 # # # # #
# 2 # 3 # # # # #
# 27 # 29 # # # # #
# 5 # 7 # 8 # # #
# 30 # 33 # 34 # 39 #
# 13 # 16 # # # # #

• Deleting, 19, 20, 24


• Deletion B+ Trees
• Order, m = 5
p1 5 p2 13 p3 17 p4 30 p5

# 2 # 3 # # # # # # 17 # 22 # 27 # 29 #

# 5 # 7 # 8 # # # # 30 # 33 # 34 # 39 #

# 13 # 16 # # # # #

• Deleting, 19, 20, 24


Sorting

• It is about arrange a given list of numbers, letters etc. in some


defined order, like ascending, descending, lexicographical etc.
1. Bubble Sort
1 2 3 4 5 6 7 8 9 10
Array 90 3 44 2 22 53 67 44 21 8

• Procedure:
• Pass-1: compare(A[1] and A[2]) and do the needful, then
compare(A[2] and A[3]) and do the needful and so on…finally,
compare(A[n-1] and A[n]).
• Pass-2: compare(A[1] and A[2]) and do the needful, then
compare(A[2] and A[3]) and do the needful and so on…finally,
compare(A[n-2] and A[n-1]).
• Pass-(n-1): compare(A[1] and A[2]) and do the needful.
1. Bubble Sort
1 2 3 4
90 3 44 2
Array
• Example: Sort in Ascending Order:
• Pass-1:
• compare(A[1] and A[2])=> A[1]=3 and A[2]=90.
• compare(A[2] and A[3]) => A[2]=44 and A[3]=90.
• compare(A[3] and A[4]) => A[3]=2 and A[4]=90.
1 2 3 4
3 44 2 90
1. Bubble Sort
1 2 3 4
3 44 2 90
Array

• Example: Sort in Ascending Order:


• Pass-2:
• compare(A[1] and A[2])=> A[1]=3 and A[2]=44.
• compare(A[2] and A[3]) => A[2]=2 and A[3]=44.
1 2 3 4
3 2 44 90
1. Bubble Sort
1 2 3 4
3 2 44 90
Array

• Example: Sort in Ascending Order:


• Pass-3:
• compare(A[1] and A[2])=> A[1]=2 and A[2]=3.

1 2 3 4
2 3 44 90
1. Bubble Sort
• Algorithm:
• Step-1: repeat step-2 for(i=1 to n-1)
• Step-2: {repeat for(j= 1 to n-i)
• {if(A[j] > A[j+1])
• swap(A[j] and A[j+1)
• }
• }
• Step-3: End
• Time Complexity: O(n2).
Array
2. Selection Sort
1 2 3 4 5 6 7 8 9 10
90 3 44 2 22 53 67 44 21 8
• Procedure:
• Pass-1:
• Find the location of the smallest element in the array and then
swap A[location] and A[0].
• Pass-2: c
• Find the location of the smallest element in the array, from A[1]
to A[n] and then swap A[location] and A[1].
• Pass-(n-1):
• Find the location of the smallest element in the array, from A[n-1]
to A[n] and then swap A[location] and A[n-1].
2. Selection Sort
Array 1 2 3 4
90 3 444 2

• Example: Sort in Ascending Order:


• Pass-1:
• Find the location smallest element from A[1] to A[4]) and Swap
A[location] and A[1].
• => Location=4 and Swap A[4] and A[1]
• =>A[1]=2 and A[4]=90.
1 2 3 4
2 3 444 90
2. Selection Sort
Array 1 2 3 4
2 3 444 90

• Example: Sort in Ascending Order:


• Pass-2:
• Find the location smallest element from A[2] to A[4]) and Swap
A[location] and A[2].
• => Location=2 and Swap A[2] and A[2]
• =>A[2]=3 and A[2]=3.
2. Selection Sort
Array 1 2 3 4
2 3 444 90

• Example: Sort in Ascending Order:


• Pass-3:
• Find the location smallest element from A[3] to A[4]) and Swap
A[location] and A[3].
• => Location=4 and Swap A[4] and A[3]
• =>A[3]=90 and A[4]=444.
1 2 3 4
2 3 90 444
2. Selection Sort
• Algorithm:
• Step-1: repeat step-2 and step-3 for(k=1 to n-1)
• Step-2: { FindSmallest(A, k, n, location)
• Step-3: Swap A[k] with A[location]
• }
• Step-4: End

• Time Complexity: O(n2).


2. Selection Sort
• Algorithm FindSmallest(A, k, n, location):
• Step-1: set location=k
• Step-2: set small=A[k]
• Step-3: repeat for(j=k+1 to n-1)
• Step-4: {if(small > A[j])
• { small = A[j]
• location = j
• }
• }
• Step-5: End
3. Insertion Sort
Array 1 2 3 4 5 6 7 8 9 10
90 3 44 2 22 53 67 44 21 8

• Procedure:
• Divide the array into sorted set and unsorted set
• Initialize A[1] to be the only element in the sorted set and rest in
the unsorted set.
• Pass-1:
• Pick the first element of the unsorted set i.e., A[2] and insert it in
its proper location in the sorted set by comparing first with the
last elements of the sorted set and then the next last element and
so on.
3. Insertion Sort
• Procedure:
• Pass-2:
• Pick the first element of the unsorted set i.e., A[3] and insert it in
its proper location in the sorted set by comparing first with the
last elements of the sorted set and then the next last element and
so on.
• Pass-(n-1):
• Pick the first element of the unsorted set i.e., A[n] and insert it in
its proper location in the sorted set by comparing first with the
last elements of the sorted set and then the next last element and
so on.
3. Insertion Sort
1 2 3 4
Array
90 3 44 2
• Example:
• A[1]=90 is the only element in sorted set and rest are in unsorted
set.
• Pass-1:
• Let temp=A[2] and compare temp with A[1]
• Compare, temp < A[1], Since true So, Swap them
• => A[1]=3 and A[2]=90
• There are no more elements in the sorted set to be compared, so
stop comparison. 1 2 3 4
• Now A[1] and A[2] are in sorted set. 3 90 44 2
3. Insertion Sort
Array 1 2 3 4
3 90 44 2

• Example:
• Pass-2:
• Let temp=A[3] and compare it with A[2]
• Compare, temp < A[2], Since true So, => A[3]=A[2]
• => A[3]=90
• Compare, temp < A[1], Since false So, A[2]=temp
• => A[2]=44 & Stop comparison.
• Now A[1], A[2] and A[3] are in sorted set.
1 2 3 4
3 44 90 2
3. Insertion Sort
1 2 3 4
3 44 90 2
• Example:
• Pass-3:
• Let temp=A[4] and compare it with A[3]
• Compare, temp < A[3], Since true So, => A[4]=A[3]=> A[4]=90
• Compare, temp < A[2], Since true, So,=> A[3]=A[2]=>A[3]=44
• Compare, temp < A[1], Since true, So,=> A[1]=temp=>A[1]=2
• Stop comparison.
• Now A[1], A[2],A[3] and A[4] are in sorted set. 1 2 3 4
2 3 44 90
• Algorithm:
3. Insertion Sort
Step-1: Repeat Step-2 to Step-5 for(k=2 to n)
Step-2: {set temp=A[k]
Step-3: set j=(k-1)
Step-4: Repeat While(temp<= A[j])
{set A[j+1] = A[j]
set j=j-1
}
set A[j+1]=temp
}
Step-5: End
Time Complexity = O(n2).
4. Merge Sort

• Procedure:
• If the array has only one element, then it is sorted
• Otherwise, divide the array into two sub-arrays of equal size
• Use merge-sort algorithm to recursively sort the two sub-arrays
• Merge the two sub-arrays to form a single sorted list.
Example: 4. Merge Sort
1 2 3 4 5 6 7 8
Array 90 3 44 2 22 53 67 45
Phase-1:
1 2 3 4 1 2 3 4
90 3 44 2 22 53 67 45

1 2 1 2 1 2 1 2
90 3 44 2 22 53 67 45

1 1 1 1 1 1 1 1
90 3 44 2 22 53 67 45
Example: 4. Merge Sort
1 2 3 4 5 6 7 8
2 3 22 44 45 53 67 90
Phase-2:
1 2 3 4 1 2 3 4
2 3 44 90 22 45 53 67

1 2 1 2 1 2 1 2
3 90 2 44 22 53 45 67

1 1 1 1 1 1 1 1
90 3 44 2 22 53 67 45
4. Merge Sort
Merge Algorithm:
A is an Array and p, q, r are indices of the array, such that p <= q < r.
Sub-array A[p…q] and A[q+1,…..r are in sorted order

MERGE(A,p,q,r)
{ n1=q-p+1 //no. of elements in sub-array 1
n2=r-q // no. of elements in sub-array 2
Let L[1…n1+1] and R[1…n2+1] be new arrays
for(i=1 to n1)
L[i]=A[p+i-1]
for(j=1 to n2)
R[j]=A[q+j]
L[n1+1]=∞
R[n2+1]=∞
4. Merge Sort
Merge Algorithm:
i=1 and j=1
for(k = p to r)
{if(L[i]<=R[j])
{ A[k]=L[i]
i=i+1}
else
{A[k]=R[j]
j=j+1
}
}
4. Merge Sort
Merge-Sort Algorithm:

MERGE-SORT(A, p, r)
{ if(p < r)
{ q = floor((p+r)/2)
MERGE-SORT(A, p, q)
MERGE-SORT(A, q+1, r)
MERGE(A, p, q, r)
}
}

Time complexity = O(nlog(n))


Space Complexity =O(n)
5. Heap-Sort
Phase-1: Build a min/max heap using the elements of Array
Phase-2: Repeatedly delete the root element of the heap
Time Complexity = O(nlog(n))
6. Quick-Sort
Procedure:
1. Partition the array A[p…r] into two sub-arrays A[p…q-1] and A[q+1…r],
such that each element of A[p…q-1] is less than or equal to A[q], which in turn is
less than or equal to A[q+1…r].
2. Compute the index q as part of this portioning procedure.
3. Sort the two sub-arrays A[p…q-1] and A[q+1…r] by recursively calling quicksort.
p=1, 6. Quick-Sort r =8,
Example:
1 2 3 4 5 6 7 8
2 8 7 1 3 5 6 4
i=0, j=1,
1. PARTITION(A,p,r)
2. {Initialized i= (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort r =8,
Example:
1 2 3 4 5 6 7 8
2 8 7 1 3 5 6 4
i=0, j=1,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 8 7 1 3 5 6 4
j=1, r =8,
i=1,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 8 7 1 3 5 6 4
j=2, r =8,
i=1,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 8 7 1 3 5 6 4
j=3, r =8,
i=1,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 8 7 1 3 5 6 4
i=1, j=4, r =8,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 1 7 8 3 5 6 4
i=2, j=3, r =8,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 1 3 8 7 5 6 4
i=3, j=6, r =8,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 1 3 8 7 5 6 4
i=3, j=6, r =8,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 1 3 8 7 5 6 4
i=3, j=6, r =8,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
p=1, 6. Quick-Sort
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
i=3, j=6, r =8,
1. PARTITION(A,p,r)
2. {Initialized i = (p-1)=0
3. Select the pivot x to be the last element of array A[r] => x= A[r]
4. for(j=p to (r-1))
5. {if(A[j] <= x
6. i++
7. exchange A[i] with A[j]
8. }
9. Exchange A[i+1] with A[r]
10. Return (i+1)}
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
i=0,
j=1,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
i=0,
j=1,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8

i=1, j=2,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
j=2,
i=2,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
i=0, j=1,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
i=0, j=1,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
2 1 3 4 7 5 6 8
i=0, j=1,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
1 2 3 4 7 5 6 8
i=0, j=1,
6. Quick-Sort
p=1, r =3,
Example:
1 2 3 4 5 6 7 8
1 2 3 4 7 5 6 8
i=0, j=1,

• Similary, Sort the other partitions


6. Quick-Sort
Algorithm:

QUICK-SORT(A, p, r)
{ if(p < r)
{ q = PARTITION(A, p, r)
QUICK-SORT(A, p, q-1)
QUICK-SORT(A, q+1, r)
}
}

Worst Case Time complexity = O(n2)


7. Randomized Quick-Sort
Algorithm:

Randomized_Partition(A, p, r)
{ i=Random(p,r)
exchange A[r] with A[i]
return PARTITION(A, p, r)
}
7. Randomized Quick-Sort
Algorithm:

RANDOMIZED_QUICK-SORT(A, p, r)
{ if(p < r)
{ q = Randomized_Partition (A, p, r)
RANDOMIZED_QUICK-SORT(A, p, q-1)
RANDOMIZED_QUICK-SORT(A, q+1, r)
}
}

Average Case Time complexity = Ɵ(nlog(n))


8. Counting Sort

• It assumes that each of the elements of the Array is an integer in the range 0
to k.
• For each element ‘x’ it determines the number of elements less than ‘x’.
• This information is then used to place the element ‘x’ directly into its
position in the output array.
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Frequency Array 0 0 0 0 0 0
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Frequency Array
2 0 2 3 0 1
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 0 2 3 0 1
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 2 3 0 1
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 3 0 1
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 7 0 1
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 7 7 1
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 7 7 8

1 2 3 4 5 6 7 8
Output Array B
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 7 7 8

1 2 3 4 5 6 7 8
Output Array B 3
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 7 7 8

1 2 3 4 5 6 7 8
Output Array B 3

0 1 2 3 4 5
Position Array F 2 2 4 6 7 8
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 6 7 8

1 2 3 4 5 6 7 8
Output Array B 0 3
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 2 2 4 6 7 8

1 2 3 4 5 6 7 8
Output Array B 0 3

0 1 2 3 4 5
Position Array F 1 2 4 6 7 8
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 1 2 4 6 7 8

1 2 3 4 5 6 7 8
Output Array B 0 3 3
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 1 2 4 6 7 8

1 2 3 4 5 6 7 8
Output Array B 0 3 3

0 1 2 3 4 5
Position Array F 1 2 4 5 7 8
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 1 2 4 5 7 8

1 2 3 4 5 6 7 8
Output Array B 0 2 3 3
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 1 2 4 5 7 8

1 2 3 4 5 6 7 8
Output Array B 0 2 3 3

0 1 2 3 4 5
Position Array F 1 2 3 5 7 8
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 1 2 3 5 7 8

1 2 3 4 5 6 7 8
Output Array B 0 0 2 3 3
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 1 2 3 5 7 8

1 2 3 4 5 6 7 8
Output Array B 0 0 2 3 3

0 1 2 3 4 5
Position Array F 0 2 3 5 7 8
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 0 2 3 5 7 8

1 2 3 4 5 6 7 8
Output Array B 0 0 2 3 3 3
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 0 2 3 5 7 8

1 2 3 4 5 6 7 8
Output Array B 0 0 3 2 3 3 3 3

0 1 2 3 4 5
Position Array F 0 2 3 4 7 8
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 0 2 3 4 7 8

1 2 3 4 5 6 7 8
Output Array B 0 0 2 3 3 3 5
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 0 2 3 4 7 8

1 2 3 4 5 6 7 8
Output Array B 0 0 3 2 3 3 3 5

0 1 2 3 4 5
Position Array F 0 2 3 4 7 7
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 0 2 3 4 7 7

1 2 3 4 5 6 7 8
Output Array B 0 0 2 2 3 3 3 5
8. Counting Sort
Example:
1 2 3 4 5 6 7 8
Input Array A 2 5 3 0 2 3 0 3

0 1 2 3 4 5
Position Array F 0 2 3 4 7 7

1 2 3 4 5 6 7 8
Output Array B 0 0 2 2 3 3 3 5
Algorithm:
8. Counting Sort
COUNTING-SORT(A, B, k)
{ create a new array F[0…k]
for(i= 0 to k)
F[i] = 0
for(j= 1 to A.length)
F(A[j]] = C[A[j]]+1
for(i= 1 to k)
F[i] = F[i] + F[i-1]
for(j= A.length downto 1)
{B[F[A[j]]] = A[j]
C[A[j]] = C[A[j]]-1
} Time complexity = Ɵ(k+n)
}
9. Radix Sort
• Integers are sorted according to the least significant and then according to
next higher significant digits and so on.

Input Pass-1 Pass-2 Pass-3


329 720 720 329
457 355 329 355
657 436 436 436
839 457 839 457
436 657 355 657
720 329 457 720
355 839 657 839
9. Radix Sort
Algorithm:

Radix-Sort(A, d)
{ //d=no. of digits in the highest input data
for (i= 1 to d)
use a stable sort(bubble, insertion, counting) to sort array A on digit i.
}

Time complexity = Ɵ(d(n+k)), assuming counting sort is used.


10. Bucket Sort
Procedure:

• Create Buckets based on some parameter


• Insert the elements of input array into specific buckets using some
parameter
• Sort the elements in the bucket using some algorithm
• Append the contents of the bucket to get the sorted list
10. Bucket Sort
Example:
Input Bucket Bucket

345 0 022 0 022


654 1 123 1 123
924 2 2
123 3 345 3 345
567 4 4
472 5 567,555 5 555,567
555 6 654 6 654
808 7 7
911 8 808 8 808
022 9 924,911 9 911,924
10. Bucket Sort
Algorithm:
Bucket-Sort(A)
{ create bucket B[0…n-1]
n=A.length
for(i=o to n-1)
make B[i] empty
for(i=1 to n)
insert A[i] into Bucket B[floor(A[i]/100)] // some scheme
for(i=0 to n-1)
sort Bucket B[i] with some sorting algorithm
Concatenate the buckets B[0], B[1]…B[n-1] in order
}
Time complexity = Ɵ(n)
External Sorting
• Used to sort when data in external/secondary disk can not fit into main
memory
Example: 11. Two Way External Sorting
• Divide the RAM into two input & one output Buffer of
equal size RAM
(Capacity = 9 numbers)

Input Buffer

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Divide the input file into blocks of size 3,
• So that each block can fit into each input buffer RAM
(Capacity = 9 numbers)

Input Buffer

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer
3 1 2

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer
1 2 3

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer
1 2 3

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Temporary File-1 Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer
1 2 3

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Temporary File-1 Output
1 2 3 Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• Pass-0:
RAM
(Capacity = 9 numbers)

Input Buffer
10 13 14

Input File
3 1 2 6 5 4 17 9 8 15 12 11 14 13 10
Temporary File-1 Output
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14 Buffer
Input Buffer

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
3 2 1
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

Temporary File-2 Output


6 5 4 Buffer
Input Buffer

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

1 2 3

Temporary File-2 Output


6 5 4 Buffer
Input Buffer

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

1 2 3

Temporary File-2 Output


6 5 4 Buffer
1 2 3
Input Buffer

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

4 5 6

Temporary File-2 Output


Buffer
1 2 3 4 5 6
Input Buffer

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
17 9 8
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

Output
6 5 4 Buffer
1 2 3 4 5 6
Input Buffer
Temporary File-2

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

Output
Buffer
1 2 3 4 5 6 8 9 11 12 15 17
Input Buffer
Temporary File-2

External Disk
• Pass-1: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-1
1 2 3 4 5 6 8 9 17 11 12 15 10 13 14

Output
Buffer
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14
Input Buffer
Temporary File-2

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
3 2 1
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Temporary File-3 Output


11 9 8 Buffer
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
6 5 4
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

1 2 3

Temporary File-3 Output


11 9 8 Buffer
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
6 5 4
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Temporary File-3 Output


11 9 8 Buffer
1 2 3
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

4 5 6

Temporary File-3 Output


11 9 8 Buffer
1 2 3
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Temporary File-3 Output


11 9 8 Buffer
1 2 3 4 5 6
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

8 9 11

Temporary File-3 Output


17 15 12 Buffer
1 2 3 4 5 6
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

12 15 17

Temporary File-3 Output


Buffer
1 2 3 4 5 6 8 9 11
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Temporary File-3 Output


Buffer
1 2 3 4 5 6 8 9 11 12 15 17
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
14 13 10
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Temporary File-3 Output


Buffer
1 2 3 4 5 6 8 9 11 12 15 17
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

10 13 14

Temporary File-3 Output


Buffer
1 2 3 4 5 6 8 9 11 12 15 17
Input Buffer

External Disk
• Pass-2: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-2
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

10 13 14

Temporary File-3 Output


Buffer
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14
Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Output
Buffer
Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
3 2 1
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Output File Output


14 13 10 Buffer
Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
6 5 4
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

1 2 3

Output File Output


14 13 10 Buffer
Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
6 5 4
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Output File Output


14 13 10 Buffer
1 2 3 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
11 9 8
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

4 5 6

Output File Output


14 13 10 Buffer
1 2 3 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
11 9 8
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

8 9 10

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
11 9 8
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
11 9 8
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

11

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

11

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
17 15 12
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

11

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
17 15 12
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

11 12 13

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
17 15 12
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 11 12 13 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
17 15 12
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

14 15 17

Output File Output


14 13 10 Buffer
1 2 3 4 5 6 8 9 10 11 12 13 Input Buffer

External Disk
• Pass-3: 11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
Temporary File-3
1 2 3 4 5 6 8 9 11 12 15 17 10 13 14

Output File Output


Buffer
1 2 3 4 5 6 8 9 10 11 12 13 14 15 17 Input Buffer

External Disk
11. Two Way External Sorting
RAM
(Capacity = 9 numbers)

Input Buffer
File

1 2 3 4 5 6 8 9 10 11 12 13 14 15 17

Output
Buffer
Input Buffer

External Disk
11. Two Way External Sorting
• The amount of data that can be held in the input buffers of RAM is called
page
• If there are P pages in a file, then
• No. of passes = ceil(log2(P))+1
• In pass-0, a block of data of size equal to a page is read from external
storage into a single input buffer of RAM, sorted and then written back to
the external storage.
• In pass-1, two blocks of data, each of size equal to two pages is read
simultaneously from external storage into a two input buffer of RAM,
sorted and then written back to the external storage.
• So total read and write operations = 2P(ceil(log2(P))+1)
• So, time complexity = O(Plog2(P))
11. Two Way External Sorting
• External merge-sort is better than merge-sort, since,
• O(Plog2(P)) << O(Nlog2(N))
• Since, P << N
12. General External Merge Sort
Input Buffers
IB-1

IB-2

Input File IB-3


Output
1 2 3 4 5
Buffer

I B – (B-1)

External Disk

Main Memory
Searching

• Finding a given data element in a given list


1. Linear/Sequential Search
1 2 3 4 5 6 7 8 9
99 176 23 422 20 6716 111 4 5

Unsorted List
• Time Complexity = O(n)
2. Binary Search
1 2 3 4 5 6 7 8 9
99 76 53 34 28 20 14 8 5

Sorted List
• Search Data = 5
• Time Complexity = O(n)
2. Binary Search
1 2 3 4 5 6 7 8 9
99 76 53 34 28 20 14 8 5

Sorted List
• Search Data = 5
• Time Complexity = O(n)
2. Binary Search
1 2 3 4 5 6 7 8 9
99 76 53 34 28 20 14 8 5

Sorted List
• Search Data = 5
• Time Complexity = O(n)
2. Binary Search
1 2 3 4 5 6 7 8 9
99 76 53 34 28 20 14 8 5

Sorted List
• Search Data = 5
• Time Complexity = O(log(n))
3. Interpolation/Extrapolation Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

low hi
Sorted List
• Search Data = 50
• When the search data is towards higher index of the array, the search
should begin towards higher index, not in the middle.
3. Interpolation/Extrapolation Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

low hi
Sorted List

• Search Data = 3
• When the search data is towards lower index of the array, the search
should begin towards lower index, not in the middle.
3. Interpolation/Extrapolation Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

low hi
Sorted List

• Search Data, x = 2.
pos = low + ceil(( high - low )*( (x – a[low]) / ( a[high] – a[low] )))
Example:
Pos = 1 + ceil((16-1)*((2-1)/(104-1)))
= 1 + ceil(15*(1/103)) = 1 + ceil(15*0.0097) = 1 + 1 = 2.
If A[pos] = = x => search data found!!!
If A[pos] > x then hi = pos-1
Else low = pos+1
3. Interpolation/Extrapolation Search
• Time Complexity = O(log(log(n))) if the data is uniformly distributed
• = O(n) otherwise
4. Jump Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

• Step size of each jump = sqrt(n) = 4


• Search data, x = 27
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

• If(A[jump-position] = = x) => found


• Else-If(A[jump-position] < x)
• jump-position = jump-position + jump-step-size
• Else-If(A[jump-position] > x)
• do backward linear search
4. Jump Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

• If(A[jump-position] = = 27) => found


• Else-If(A[jump-position] < x)
• jump-position = jump-position + jump-step-size
• Else-If(A[jump-position] > x)
• do backward linear search
4. Jump Search
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
1 2 3 6 7 10 13 16 18 22 27 33 45 50 80 104

• If(A[jump-position] = = 27) => found


• Else-If(A[jump-position] < x)
• jump-position = jump-position + jump-step-size
• Else-If(A[jump-position] > x)
• do backward linear search

• Time Complexity = O(sqrt(n))


4. Jump Search

• Step size of each jump = sqrt(n=16) = 4

• Time Complexity = O(log(log(n))) if the data is uniformly distributed


• = O(n) otherwise
Home Work

• Tree Search
• Fibonacci Search

S-ar putea să vă placă și