0% found this document useful (0 votes)
97 views

Data Structure and Algorithm All

This document provides an introduction to data structures and algorithms analysis. It defines key concepts such as data structures, algorithms, abstraction, and abstract data types. It explains that a program consists of data structures to organize data and algorithms to solve problems by performing operations on the data structures. The document also discusses properties of good algorithms, such as being finite, definite, sequential, feasible, correct, and efficient. It introduces empirical and theoretical approaches to analyzing algorithms to determine their efficiency.

Uploaded by

yomif tamiru
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
97 views

Data Structure and Algorithm All

This document provides an introduction to data structures and algorithms analysis. It defines key concepts such as data structures, algorithms, abstraction, and abstract data types. It explains that a program consists of data structures to organize data and algorithms to solve problems by performing operations on the data structures. The document also discusses properties of good algorithms, such as being finite, definite, sequential, feasible, correct, and efficient. It introduces empirical and theoretical approaches to analyzing algorithms to determine their efficiency.

Uploaded by

yomif tamiru
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 170

Introduction to Data Structures

and
Algorithms Analysis

Injibara University

1
DT and AL

• What is program?
It is a set of instruction which is written in order to solve a
problem
• What is solution?
A solution to a problem actually consists of two things:
o A way to organize the data
o Sequence of steps to solve the problem
• What is data structure ?
 It is the way data are organized in a computer’s memory
• What algorithm?
It is the sequence of computational steps to solve a problem
A program is nothing but data structures plus algorithms.
Injibara University 2
Introduction to data structure
• How data structure are used to model the
world or part of the world?
The value held by a data structure represents some
specific characteristics of the world
The characteristics being modeled restricts the
possible values held by a data structure and the
operations to be performed on the data structure

Injibara University 3
Introduction to data structure

• For a given problem


– The first step to solve the problem is obtaining one’s
abstract view ,or model, of the problem and this
process of modeling is called abstraction
• The model defines an abstract view to
the problem
• This implies that the model focuses only
on problem related stuff and that a
programmer tries to define the
properties of the problem.

Injibara University 4
Introduction to data structure

• These properties include


– The data which are affected and
– The operations that are involved in the problem
• With abstraction you create a well-defined entity that
can be properly handled. These entities define the data
structure of the program.
• An entity with the properties just described is called an
abstract data type (ADT).
Injibara University 5
Abstraction
• Abstraction is a process of classifying
characteristics as relevant and irrelevant for
the particular purpose at hand and ignoring the
irrelevant ones.
– Example: model Customer of CBE
Relevant None relevant

• Char Name[15] • Height


• Varchar AccounNo[13] • Color
• Int Age, year • Race
• Int phoneNumber

Injibara University 6
Abstract Data Type (ADT)
• Abstract data types consists of data to be stored
and operation supported on them
• Abstract data type is a specification that describes
a data set and the operation on that data
• ADT specifies
What data is stored
What operation can be done on the data
• It does not specify how to store or how to
implement the operation
• It is also independent of any programming
language
Injibara University 7
Abstract Data Type (ADT)

Example
• ADT employees of an organization:
• This ADT stores employees with their relevant
attributes and discarding irrelevant attributes
– Relevant : Name, AccountNo, Sex, Age, PhoneNo
– Irrelevant : height, color , race
• This ADT supports Witdrawal, deposite,
transfer, checkbalance … operations

Injibara University 8
Abstract Data Type (ADT)
• In contract a data structure is a language construct that the programmer
has defined in order to implement an abstract data type
• What is the purpose of data structures in programs?
– Data structures are used to model a problem
• Example
Struct student_record
{
Char name[20];
Varchar ID-NO[8];
Char Department[10];
Int age;
};
• Attribute of each variables: Name, address, scope, type,size, life time,

Injibara University 9
Algorithm
• Algorithm
– It concise specification of an operation for solving a problem.
– It is a well defined computational procedure that takes some value
or a set of values as input and produces some value or a set of
values as output
– Input  algorithm  outputs
• Basic Difference between data structure and algorithm
– Data structures model the static part of the world. They are
unchanging while the world is changing.
– In order to model the dynamic part of the world we need to work
with algorithm
– An algorithm transforms data structures from one state to another
state

Injibara University 10
Algorithm
• What is the purpose of algorithm in programs?
– Take value as input :
• Example: cin>> age;
– Change the value held by data structures:
• Example: age= age+1
– Change the organization of the data structure
• Example: sort student by name
– Produce output
• Example: display student’s information

Injibara University 11
Algorithm
• Quality of data structure and algorithm
– The quality of a data structure is related to its
ability to successfully model the characteristics of
the world(problem).
– The quality of an algorithm is related to its ability
to successfully simulates the changes in the world.
– The quality of data structure and algorithms is
determined by their ability to work together well.
Correct data structures lead to simple and
efficient algorithms. And correct algorithms
lead to accurate and efficient data structures
Injibara University 12
Properties Algorithm
• Finiteness
– Algorithm must complete after a finite number of steps.
• Definiteness (absence of ambiguity)
– Each step must be clearly defined, having one and only one interpretation
• Sequential :
– each step must have a uniquely defined preceding and succeeding step. The first step( start step) and last
step (halt step) must be clearly noted
• Feasibility
– it must be possible to perform each instruction.
– Each instruction should have possibility to be executed.
Example
For (int i=0, i<0; i++)
cout<<I; // there is no possibility that this statement to be executed because the condition Is false from the
beginning
• Correctness
– it must compute correct answer for all possible legal inputs.
– The output should be as expected and required and correct

Injibara University 13
Properties Algorithm
• Language independence
• Completeness
– it must solve the problem completely
• Effectiveness
– doing the right thing. It should yield the correct result all the time for all of the possible
cases
• Efficiency ( time and space)
– it must solve with the least amount of computational resources such as time and space.
Example 1: write a program that takes two numbers and displays the sum of the two .

Program a: Program b: Program c ( the most efficient)


Cin>> a; Cin>> a; Cin>> a;
Cin>>b; Cin>>b; Cin>>b;
Sum=a+b; a=a+b; Cout<<a+b;
Cout<< sum; Cout<< a;

All are effective but with different efficiencies


Injibara University 14
Properties Algorithm
• Input/output
• Precision
– the result should always be the same if the algorithm is
given identical input
• Simplicity
– a good general rule is that each step should carry out one
logical step.
– What is simple to one processor may not be simple to
another.
• Level of abstraction

Injibara University 15
Algorithm Analysis
• It refers analysis to the process of determining how much
computing time and storage that algorithms will require.
• In other words, it’s a process of predicting the resource requirement
of algorithm in a given environment
• The main resources are
– Running Time
– Memory Usage
– Communication Bandwidth
• Running time is the most important since computational time is the
most precious resource in most problem domains
• There are two approaches to measure the efficiency of algorithms:
1. Empirical
2. Theoretical

Injibara University 16
Empirical Analysis
• It works based on the total time of the program.
• It uses the actual system clock time
• Example:
t1(Initial time before the program starts)
for(int i=0; i<=10; i++)
cout<<i;
t2 (final time after the execution of the program is
finished)
Running time taken by the above algorithm (TotalTime) = t2-t1;
• It is difficult to determine efficiency of algorithms using this
approach, because clock-time can vary based on many factors.

Injibara University 17
Empirical Analysis
• Factor examples: c) Specific data for a particular run of
the program
a) Processor speed of the computer Input size
78GHz ==> 10s Input properties
12GHz ==> 15s t1
b) Current processor load for(int i=0; i<=n; i++)
Only the work 10s cout<<i;
With printing 15s With printing & t2
browsing the internet >15s T=t2-t1;
For n=100, T>=0.5s
n=1000, T>0.5s
d) Operating System
Multitasking Vs Single tasking
Internal structure

Injibara University 18
Theoretical Algorithm Analysis
• Determining the quantity of resources required using
mathematical concept.
• Analyze an algorithm according to the number of basic
operations (time units) required, rather than according to an
absolute amount of time involved.
• We use theoretical approach to determine the efficiency of
algorithm because:
– The number of operation will not vary under different conditions.
– It helps us to have a meaningful measure that permits comparison of
algorithms independent of operating platform.
– It helps to determine the complexity of algorithm.

Injibara University 19
Theoretical Algorithm Analysis
• Complexity Analysis is the systematic study of the cost of
computation, measured either in:
– Time units
– Operations performed,
– The amount of storage space required.
• Two important ways to characterize the effectiveness of an
algorithm are its Space Complexity and Time
Complexity.
– Time Complexity: Determine the approximate amount of time
(number of operations) required to solve a problem of size n.
– Space Complexity: Determine the approximate memory
required to solve a problem of size n.
Injibara University 20
Theoretical Algorithm Analysis
• Complexity analysis involves two distinct phases:
– Algorithm Analysis
– Order of Magnitude Analysis
• Algorithm Analysis
– Analysis of the algorithm or data structure to produce a function T(n)
that describes the algorithm in terms of the operations performed in
order to measure the complexity of the algorithm.
• Order of Magnitude Analysis
– Analysis of the function T (n) to determine the general complexity
category to which it belongs.
• There is no generally accepted set of rules for algorithm
analysis.
• However, an exact count of operations is commonly used.

Injibara University 21
Analysis Rules:
– To count the number of operations we can use the following Analysis
Rule.
1. Assume an arbitrary time unit.
2. Execution of one of the following operations takes time 1
unit:
– Assignment Operation
• Example: i=0;
– Single Input/Output Operation
• Example: cin>>a; cout<<“hello”;
– Single Boolean Operations
• Example: i>=10
– Single Arithmetic
• Example: a+b;
– Function Return
• Example: return sum; Injibara University 22
Analysis Rules:
3. Running time of a selection statement (if, switch) is the time for the
condition evaluation plus the maximum of the running times for the
individual clauses in the selection.
Example:
int x;
int sum=0;
if(a>b)
{
sum= a+b;
cout<<sum;
}
else
{
cout<<b;
}
T(n) = 1 +1+max(3,1) = 5

Injibara University 23
Analysis Rules:
4. Loop statements
•  The running time for the statements inside the
loop * number of iterations + time for setup(1) + time for checking
(number of iteration + 1) + time for update (number of iteration).
• The total running time of statements inside a group of
nested loops is the running time of the statements * the
product of the sizes of all the loops.
– For nested loops, analyze inside out.
• Always assume that the loop executes the maximum
number of iterations possible.
– (Why?) Because we are interested in the worst case complexity.

Injibara University 24
Analysis Rules:
5. Function call: 1 for setup + the time for any parameter calculations + the time
required for the execution of the function body.

Examples: 1 Example 2
int i=0;
int k=0,n;
while(i<n)
cout<<“Enter an {
integer”; cout<<i; i++;
cin>>n }
int j=1;
for(int i=0;i<n; i++) while(j<=10)
k++; {
T(n)=3+1+n+1+n+n=3n+ cout<<j; j++;
}
5
T(n)=1+n+1+n+n+1+11+2(10) = 3n+34 
Injibara University 25
Analysis Rules:

Examples: 3 Example 4
int k=0; int sum=0;
for(i=1;i<=n;i++))
for(int i=1 ; i<=n; i++)
sum=sum+i;
for( int j=1; j<=n; j++) T(n)=1+1+(n+1)+n+(1+1)n
k++; =3+4n=O(n) 
T(n)=1+1+(n+1)+n+n(1+
(n+1)+n+n) = 2n+3+n(3n+2)
= 2n+3+3n2+2n = 3n2+4n+3
4).
Injibara University 26
Example 6
Example 5 void func( )
{
int counter()
int x=0;
{ int i=0;
int a=0; int j=1;
cout<<”Enter a number”;
cout<<”Enter a number”;
cin>>n;
cin>>n; while(i<n){ i=i+1;
for(i=0;i<n;i++) }
while(j<n)
a=a+1;
{
return 0; j=j+1;
} }
T(n)=1+1+1+(1+n+1+n)+2n+1 }
T(n)=1+1+1+1+1+n+1+2n+n+2(n-1) = 6+4n+2n-2
=4n+6=O(n) =4+6n=O(n)
Injibara University 27
Example 8:
Example 7:
int sum=0;
int sum(int n)
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
int s=0;
sum++;
for(int i=1;i<=n;i++)
T(n)=1+1+(n+1)+n+n*(1+
s=s+(i*i*i*i); (n+1)+n+n)
return s; =3+2n+n2+2n+2n2 =3+2n+3n2+2n
} =3n2+4n+3=O(n2)
T(n)=1+(1+n+1+n+5n)+1
=7n+4=O(n)
Injibara University 28
Formal Approach to Analysis

• for Loops: Formally


– In general, a for loop translates to a summation. The
index and bounds of the summation are the same as the
index and bounds of the for loop.
N
for (int i = 1; i <= N; i++) {

}
sum = sum+i;
i 1
1  N
– Suppose we count the number of additions that are done.
There is 1 addition per iteration of the loop, hence N
additions in total.
Injibara University 29
Formal Approach to Analysis

• Nested Loops: Formally


• Nested for loops translate into multiple
summations, one for each for loop.
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= M; j++) { N M N

}
sum = sum+i+j;  2   2M  2MN
i 1 j 1 i 1
}

• Again, count the number of additions. The


outer summation is for the outer for loop.

Injibara University 30
Formal Approach to Analysis
• Consecutive • Conditionals: Formally
Statements: Formally • If (test) s1 else s2:
• Add the running times Compute the maximum
of the separate blocks of the running time for
of your code s1 and s2.  
 N
2

2 N 
 N  2N
1 2
N
1, 2N
j

 N 2  
N  i 1
   
 1   i 1 j 1 
{ N  x  i 2
ma 
1
i++)
N ;
2N
i 1  
= ,
1; i < ;
int i =
for ( m = sum
+i
 +)
{
axN
){ ; i+ m
su
= N ; i++ ++) { { i <=
N
j {
} i = 1; i < j <= N; )
= 1 = 1; +i; + +) +) {
in t 1 ; j; = i j+
for ( r (int j = sum+i+ te st nt i sum = N; N ;
i
fo
sum
= if ( for ( m = ; i < j <= +j;
su 1 1; i
t i = j = um+
} (in (int = s
}} e for for sum
} els
Injibara University 31
Categories of Algorithm Analysis
1. Best Case Analysis
– Best case analysis assumes the input data are arranged
in the most advantageous order for the algorithm.
– the smallest possible set of inputs and causes execution
of the fewest number of statements.
– it computes the lower bound of T(n), where T(n) is the
complexity function.
• Examples: For sorting algorithm
– If the list is already sorted (data are arranged in the
required order).
– For searching algorithm If the desired item is located at
first accessed position.
Injibara University 32
Categories of Algorithm Analysis
2. Worst Case Analysis
– Worst case analysis assumes the input data are
arranged in the most disadvantageous order for the
algorithm
– Takes the worst possible set of inputs. Causes execution
of the largest number of statements.
– Computes the upper bound of T(n) where T(n) is the
complexity function.
• Example:
– While sorting, if the list is in opposite order.
– While searching, if the desired item is located at the last
position or is missing.
Injibara University 33
Categories of Algorithm Analysis
3. Average Case Analysis
– Determine the average of the running time overall permutation of input
data.
– Takes an average set of inputs.
– It also assumes random input size.
– It causes average number of executions.
– Computes the optimal bound of T(n) where T(n) is the complexity
function.
– Sometimes average cases are as bad as worst cases and as good as best
cases.
• Examples:
– For sorting algorithms, While sorting, considering any arrangement
(order of input data).
– For searching algorithms While searching, if the desired item is located
at any location or is missing.
Injibara University 34
Categories of Algorithm Analysis
– Worst case analysis is the most common analysis
because, it provides the upper bound for all input
(even for bad ones).
– Average case analysis is often difficult to determine
and define. If situations are in their best case, no
need to develop algorithms because data
arrangements are in the best situation.
– Best case analysis cannot be used to estimate
complexity. We are interested in the worst case time
since it provides a bound for all input-this is called the
“Big-Oh” estimate.

Injibara University 35
Asymptotic Analysis

• Asymptotic analysis is concerned with how the


running time of an algorithm increases with the
size of the input in the limit, as the size of the input
increases without bound.
• There are five notations used to describe a running
time function. These are:
– Big-Oh Notation (O)
– Big-Omega Notation ()
– Theta Notation ()
– Little-o Notation (o)
– Little-Omega Notation ()
Injibara University 36
Big-Oh Notation (O)
• used for computing the complexity of algorithms;
i.e., the amount of time that it takes for computer
program to run
• It’s only concerned with what happens for a very
large value of n
• For example: f(n)= n2-n
– if the number of operations in an algorithm is n2 – n, n
is insignificant compared to n2 for large values of n.
– Hence the n term is ignored. Of course, for small
values of n, it may be important.
– Big-Oh is mainly concerned with large values of n.
Injibara University 37
Big-Oh Notation (O)
• Formal Definition: f (n) = O (g (n)) if there exist
c, k ∊ ℛ+ such that for all n ≥ k,
f (n) ≤ c.g (n).
• Examples: The following points are facts that
you can use for Big-Oh problems:
– 1<= n for all n >= 1
– n <= n2 for all n >= 1
– 2n <= n! for all n >= 4
– log2n <= n for all n >= 2
– n <= nlog2n for all n >= 2
Injibara University 38
Big-Oh Notation (O)

Injibara University 39
Big-Oh Notation (O)
1. f(n) = 10n + 5 and g(n) = n. Show that f(n) is O(g(n)). To show that
f(n) is O(g(n)) we must show that constants c and k such that
f(n) <= c.g(n) for all n >= k
Or 10n + 5 <= c.n for all n >= k
Try c = 15. Then we need to show that 10n + 5 <= 15n
Solving for n we get: 5 < 5n or 1 <= n.
So f(n) =10n + 5 <= 15.g(n) for all n >= 1.
(c = 15, k = 1).
2. f(n) = 3n2 + 4n + 1. Show that f(n) = O(n2).
4n <= 4n2 for all n >= 1 and 1 <= n2 for all n >= 1
3n2 + 4n+1 <= 3n2 + 4n2 + n2 for all n >= 1
<= 8n2 for all n >= 1
So we have shown that f(n)<= 8n2 for all n >= 1
Therefore, f (n) is O(n2) (c = 8, k = 1)
Injibara University 40
Orders of Common Function
Notation Name Example

O(1) Constant Determining if a number is even or odd; using a constant-size


lookup table or hash table

O(log n) Logarithmic Finding an item in a sorted array with a binary search or a search
tree (best case)
O(n) Linear Finding an item in an unsorted list or a malformed tree (worst
case); adding two n-digit numbers

O(nlogn) Linearithmic Performing a Fast Fourier transform; heap sort, quick sort (best
case), or merge sort

O(n2) Quadratic Multiplying two n-digit numbers by a simple algorithm; adding


two n×n matrices; bubble sort (worst case or naive
implementation), shell sort, quick sort (worst case), or insertion
sort

Injibara University 41
• Example: Find Big-Oh of the following algorithm.
1)
for( int i=1;i<=n; i++)
sum=sum + i;
T(n)=2*n=2n=O(n).
2)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
k++;
T(n)=1*n*n=n2 = O(n2).

Injibara University 42
Complexity Category functions
T(n) Big-O
F(n)
c, c is constant 1 C=O(1)
10logn + 5 logn T(n)=O(logn)
√n +2 √n T(n)=O(√n)
5n+3 n T(n)=O(n)
3nlogn+5n+2 nlogn T(n)=O(nlogn)
10n2 +nlogn+1 n2 T(n)=O(n2)
5n3 + 2n2 + 5 n3 T(n)=O(n3)
2n+n5+n+1 2n T(n)=O(2n)
7n!+2n+n2+1 n! T(n)=O(n!)
8nn+2n +n2 +3 nn T(n)=O(nn)

Injibara University 43
Chapter Three
Introduction to Sorting and Searching

Injibara University 44
Introduction
Why do we study sorting and searching
algorithms?
• These algorithms are the most common and
useful tasks operated by computer system.
• Computers spend a lot of time searching and
sorting.

Injibara University 45
Simple Searching
1. Simple Searching algorithms
• Searching:- is a process of finding an element in a list
of items or determining that the item is not in the list.
– To keep things simple, we shall deal with a list of numbers.
– A search method looks for a key, arrives by parameter.
– By convention, the method will return the index of the
element corresponding to the key or, if unsuccessful, the
value -1.
• There are two simple searching algorithms:
– Sequential Search, and
– Binary Search
Injibara University 46
Sequential/linear Search
• The most natural way of searching an item.
• Easy to understand and implement.
• It is made over all items one by one
• Algorithm:
– In a linear search, we start with top (beginning) of the list,
and compare the element at top with the key.
– If we have a match, the search terminates and the index
number is returned.
– If not, we go on the next element in the list.
– If we reach the end of the list without finding a match, we
return -1.
Injibara University 47
Sequential/linear Search
i) i=1
ii) If i>n, go to step vii
iii) If Array[i]=x, go to step vi
iv) i=i+1
v) Go to step ii
vi) Print element x found at i
vii) Print element not found (index =-1 )
viii)Exit

Injibara University 48
Sequential/linear Search
int Linear_Search(int list[], int key)
{
int index=0;
int found=0;
do{
if(key==list[index])
found=1;
else
index++;
}while(found==0&&index<n);
if(found==0)
index=-1;
return index;
}
• Time is proportional to the size of input (n) and we call this time
complexity O(n) 
Injibara University 49
Binary Search
• It assumes the data is sorted it also uses divide and conquer strategy
(approach).
• Reducing the search space by two
• Algorithm:
– In a binary search, we look for the key in the middle of the list. If we get a
match, the search is over.
– If the key is greater than the element in the middle of the list, we make the
top (upper) half the list to search.
– If the key is smaller, we make the bottom (lower) half the list to search.
– Repeat the above steps (I,II and III) until one element remains.
– If this element matches return the index of the element, else
– return -1 index. (-1 shows that the key is not in the list).
– Have three cases
• Case 1: key== array[mid]
• Case 2: key < array[mid]
• Case 3: key>array[mid]

Injibara University 50
Binary Search
int Binary_Search(int list[],int k) { else
int left = 0; left = mid + 1;
int right = n - 1; }
int found = 0; }while(found = = 0&& left <=
do{ right);
mid = (left + right) / 2; if(found == 0)
if(key = = list[mid]) index = -1;
found=1; else
else{ index = mid;
if(key < list[mid]) return index;
right = mid - 1; }
The computational time for this algorithm is proportional to log 2 n Therefore the time
complexity is O(log n) (n n/2n/4 …1
Injibara University 51
:- =1 k=
Sorting Algorithms
• The following are simple sorting algorithms
used to sort small-sized lists.
– Insertion Sort
– Selection Sort
– Bubble Sort

Injibara University 52
Insertion Sort
Basic Idea:
• Find the location for an element and move all others up, and
insert the element.The process involved in insertion sort is as
follows:
– The left most value can be said to be sorted relative to itself. Thus, we
don’t need to do anything.
– Check to see if the second value is smaller than the first one. If it is,
swap these two values. The first two values are now relatively sorted.
– Next, we need to insert the third value in to the relatively sorted portion
so that after insertion, the portion will still be relatively sorted.
– Remove the third value first. Slide the second value to make room for
insertion. Insert the value in the appropriate position. Now the first
three are relatively sorted.
– Do the same for the remaining items in the list.
Injibara University 53
Insertion Sort

• Implementation
void insertion_sort(int list[]){
int temp;
for(int i = 1; i < n; i++){
temp = list[i];
for(int j = i; j > 0 && temp < list[j - 1]; j--)
{ //work backwards through the array finding where temp should go
list[j] = list[j - 1];
list[j - 1] = temp;
}//end of inner loop
}//end of outer loop
}//end of insertion_sort
Analysis
• How many comparisons?
1 + 2 + 3 +…+ (n-1) = O(n2)
• How many swaps?
1 + 2 + 3 +…+ (n-1) = O(n2)
Injibara University 54
Selection Sort
Basic Idea: for(j = i + 1; j < n; j++){
if(list[j] < list[smallest])
Loop through the array from I = 0 to n -
smallest = j;
1.
}//end of inner loop
Select the smallest element in the array temp = list[smallest];
from i to n list[smallest] = list[i];
Swap this value with value at position i. list[i] = temp;
Implementation: } //end of outer loop
void selection_sort(int list[]) }//end of selection_sort
Analysis
{
How many comparisons?
int i, j, smallest; (n-1) + (n-2) +…+ 1 = O(n2)
for(i = 0; i < n; i++){ How many swaps?
smallest = i; n = O(n)

Injibara University 55
Bubble Sort
• Bubble sort is the simplest algorithm to
implement and the slowest algorithm on very
large inputs.
• Basic Idea:
– Loop through array from i = 0 to n and swap
adjacent elements if they are out of order.

Injibara University 56
Bubble Sort
Implementation:
void bubble_sort(list[]) Analysis of Bubble
{ Sort
int i, j, temp; How many
for(i = 0; i < n; i++){ comparisons?
for(j = n-1; j > i; j--){
(n-1) + (n-2) +…+ 1 =
if(list[j] < list[j-1]){
temp = list[j];
O(n2)
list[j] = list[j-1]; How many swaps?
list[j-1] = temp; (n-1) + (n-2) +…+ 1 =
}//swap adjacent elements O(n2)
}//end of inner loop
}//end of outer loop
}//end of bubble_sort
Injibara University 57
Chapter Four
Data Structure and Its Application

Injibara University 58
Data Structure and its applications
• There are two broad types of data structure based on their
memory allocation:
– Static Data Structures
– Dynamic Data Structure
• Static Data Structures
– Static Data Structures Are data structures that are defined &
allocated before execution, thus the size cannot be changed during
time of execution.
– Example: Array implementation of ADTs.
• Dynamic Data Structure
– Dynamic Data Structure Are data structure that can grow and shrink
in size or permits discarding of unwanted memory during execution
time.
– Example: Linked list implementation of ADTs.
Injibara University 59
Data Structure and its applications
Structure
Structure is a collection of data items and the data items can be of different
data type. The data item of structure is called member of the structure.
Declaration of structure
Structure is defined using the struct keyword.
struct name
{
data type1 member 1;
data type2 member 2
.
.
.
data type n member n;
};
Injibara University 60
Data Structure and its applications
Example :
struct student
{
string name;
int age;
string Dept;
};
The struct keyword creates a new user defined
data type that is used to declare variable of an
aggregated data type.
Injibara University 61
Data Structure and its applications
Accessing Members of Structure Variables
– The Dot operator (.): to access data members of
structure variables.
– The Arrow operator (->): to access data members of
pointer variables pointing to the structure.
Example:
struct student stud;
struct student *studptr;
cout<<stud.name;
OR
cout<name;
Injibara University 62
Data Structure and its applications
Self-Referential Structures
Structures can hold pointers to instances of
themselves.
Example:
struct student
{
char name[20];
int age;
char Dept[20];
struct student *next;
};
Injibara University 63
Linked List
• Linked List is self-referential structure. It is a collection of elements
called nodes, each of which stores two types of fields. 
– Data items and a pointer to next node in the case of singly linked list and 
– pointer to previous node in the case of doubly linked list.
– The data field: holds the actual elements on the list.
– The pointer field: contains the address of the next and/or previous node
in the list.
• Adding a node to the list
Steps
– Allocate a new node.
– Set the node data values and make new node point to NULL.
– Make old last node’s next pointer point to the new node.
– *Make the new last node’s prev pointer point to the old last node. (This is
only for Double Linked list).

Injibara University 64
Linked list
• Traversing through the list
• To Move Forward:
– Set a pointer to point to the same thing as the start (head) pointer.
– If the pointer points to NULL, display the message “list is empty" and stop.
– Otherwise, move to the next node by making the pointer point to the same thing
as the next pointer of the node it is currently indicating.
• To Move Forward: (Double linked list)
– Set a pointer to point to the same thing as the start pointer.
– If the pointer points to NULL, display the message “list is empty" and stop.
– Set a new pointer and assign the same value as start pointer and move forward
until you find the node before the one we are considering at the moment.
• To Move Backward: (Double linked list)
– Set a pointer to point to the same thing as the end (tail) pointer.
– If the pointer points to NULL, display the message “list is empty" and stop.
– Otherwise, move back to the previous node by making the pointer point to the
same thing as the prev pointer of the node it is currently indicating.
Injibara University 65
Linked list
• Display the content of list
Steps:
– Set a temporary pointer to point to the same thing as the start pointer.
– If the pointer points to NULL, display the message "End of list" and stop.
– Otherwise, display the data values of the node pointed to by the start
pointer.
– Make the temporary pointer point to the same thing as the next pointer
of the node it is currently indicating.
– Jump back to step 2.
• Insert at the front (beginning)
– Allocate a new node.
– Insert new element values.
– Make the next pointer of the new node point to old head (start).
– Update head (start) to point to the new node.
Injibara University 66
Linked list

Injibara University 67
Linked List
• Inserting at the End
Steps
– Allocate a new node.
– Set the node data values and make the next pointer of the new node point to NULL.
– Make old last node’s next pointer point to the new node.
– Update end to point to the new node.
• Insertion in the middle
Steps:
– Create a new Node
– Set the node data Values
– Break pointer connection
– Re-connect the pointers
• Types of Linked List
– Single linked lists:
– Doubly linked lists
– Circular linked lists
Injibara University 68
Singly Linked List
• A singly linked list can be represented by a
diagram like shown blow

Injibara University 69
Singly linked list
• Start (Head): Special pointer that points to the
first node of a linked list, so that we can keep
track of the linked list.
– The last node should points to NULL to show that it is
the last link in the chain (in the linked list).

Injibara University 70
Singly linked list
• According to the above example in the figure, it is
the singly linked list which has four nodes in it,
each with a link to the next node in the series (in
the linked list).
• C++ implementation of singly linked list:
struct node
{
int data;
node *next;
};
node *head = NULL;
Injibara University 71
Singly linked list
• Operations of singly Linked List
– Adding a node to the end of a singly linked list
– Adding a node to the left of a specific data in a singly
linked list
– Adding a node to the right of a specific data in a singly
linked list
– Deleting a node from the end of a singly linked list
– Deleting a node from the front of a singly linked list
– Deleting any node using the search data from a singly
linked list
– Display the node from the singly linked list in a forward
manner
Injibara University 72
Singly linked list
• Adding a node to the end of a singly linked list
void insert_end(int x)
{
node *temp=new node;
temp->data=x;
temp->next=NULL;
if(head==NULL)
head = temp;
else
{
node *temp2 = head;
while(temp2->next!=NULL)
{
temp2 = temp2->next;
}
temp2->next= temp;
}
}
Injibara University 73
Singly linked list
• Adding a node to the front of a singly linked list
void insert_front(int x)
{
node *temp=new node;
temp->data=x;
temp->next=NULL;
if(head==NULL)
head = temp;
else
{
temp->next = head;
head = temp;
}
}

 
Injibara University 74
Singly linked list
Adding a node to the right of a specific value in a singly linked list

void insert_right_y(int x, int y node *temp2 = head;


) while(temp2->data!=y)
{ {
node *temp=new node; temp2 = temp2->next;
temp->data=x; }
temp->next=NULL; temp->next = temp2->next;
if(head==NULL) temp2->next = temp;
head = temp; }
else }
{
Injibara University 75
Singly Linked list

Adding a node to the left of a specific value in a singly linked list

void insert_left_y(int x, int y)
{ node *temp2 = head;
node *temp=new node; node *temp3;
temp->data=x; while(temp2->data!=y)
temp->next=NULL; {
if(head==NULL) temp3 = temp2;
head = temp; temp2 = temp2->next;
else }
{ temp->next = temp3->next;
temp3->next = temp;
}
}

Injibara University 76
Singly Linked list
• Deleting a node from the front of a singly linked list
void delete_front()
{
node *temp;
if(head==NULL)
cout <<"No data inside\n";
else
{
temp = head;
head = head->next;
delete temp;
}
}
Injibara University 77
Singly Linked list
Deleting a node from the end of a singly linked list
void delete_end()
{
node *temp, *temp3;
if(head==NULL)
cout <<"No data inside\n";
else {
temp = head;
while(temp->next!=NULL) {
temp3 = temp;
temp = temp->next;
}
temp3->next = NULL;
delete temp;
}
}
Injibara University 78
Singly Linked list
Deleting a node of specific data of a singly linked list
void delete_any(int x) {
{ temp = head;
node *temp, *temp3; while(temp->data!=x)
if(head==NULL) {
cout <<"No data inside\n"; temp3 = temp;
if(head->data==x) temp = temp->next;
{ }
temp = head; temp3->next = temp->next;
head = head->next; delete temp;
delete temp; }
} }
else
Injibara University 79
Singly Linked list
Display in a forward manner in a singly linked list
void display()
{
node *temp;
if(head==NULL)
cout << "No data inside\n";
else
{
temp = head;
while(temp!=NULL)
{
cout <<temp->data << endl;
temp = temp->next;
}
}
}
Injibara University 80
Double Linked lists
• Each node points not only to Successor node (Next
node), but also to Predecessor node (Previous node).
• There are two NULL: at the first and last nodes in the
linked list.
• Advantage: given a node, it is easy to visit its
predecessor (previous) node. It is convenient to
traverse linked lists Forwards and Backwards.

Injibara University 81
Double Linked lists
• Operations of Doubly Linked List
– Adding a node to the end of a doubly linked list
– Adding a node to the front of a doubly linked list
– Adding a node to the left of a specific data in a doubly linked list
– Adding a node to the right of a specific data in a doubly linked list
– Deleting a node from the end of a doubly linked list
– Deleting a node from the front of a doubly linked list
– Deleting any node using the search data from a doubly linked list
– Display the node from the doubly linked list in a forward manner
– Display the node from the doubly linked list in a backward manner

Injibara University 82
Double Linked lists

struct node
{
int data;
node *prev;
node *next;
};
node *head = NULL, *tail = NULL;

Injibara University 83
Double Linked lists

Adding a node to the end of a doubly linked list


void insert_end(int x) tail->next = temp;
{ temp->prev = tail;
node* temp = new node; tail = temp;
temp->data = x; }
temp->next = NULL; }
temp->prev = NULL;
if (head == NULL)
head = tail = temp;
else {
Injibara University 84
Double Linked lists

Adding a node to the front of a doubly linked list


void insert_front(int x) {
{ temp->next = head;
node* temp = new node; head->prev = temp;
temp->data = x; head = temp;
temp->next = NULL; }
temp->prev = NULL;
if (head == NULL)
head = tail = temp;
else
Injibara University 85
Double Linked lists

Adding a node to the left of a specific data in a doubly linked list

void insert_left_y(int x, int y) else
{ {
node* temp = new node; node *temp2 = head, *temp3;
temp->data = x; while(temp2->data!=y)
temp->next = NULL; {
temp->prev = NULL; temp3 = temp2;
if (head == NULL) temp2 = temp2->next;
head = tail = temp; }
else temp->next = temp3->next;
if(head->data==y) temp3->next = temp;
{ temp->prev = temp3;
temp->next = head; temp2->prev = temp;
head->prev = temp; }
head = temp; }
}

Injibara University 86
Double Linked lists

Adding a node to the right of a specific data in a doubly linked list

void insert_right_y(int x, int y) }
{ else
node* temp = new node; {
temp->data = x; node *temp2 = head;
temp->next = NULL; while(temp2->data!=y)
temp->prev = NULL; {
if (head == NULL) temp2 = temp2->next;
head = tail = temp; }
else if(temp2->next==NULL)
if(head->data==y) tail = temp;
{ temp->prev = temp2;
if(head->next==NULL) temp->next = temp2->next;
tail = temp; temp2->next->prev = temp;
temp->prev = head; temp2->next = temp;
temp->next = head->next; }
head->next->prev = temp; }
head->next = temp;
Injibara University 87
Double Linked lists
• Deleting a node from the end of a doubly linked list
void delete_end()
{
node *temp;
if(tail==NULL)
cout <<"No data inside\n";
else
{
temp = tail;
tail = tail->prev;
tail->next = NULL;
delete temp;
}
}
Injibara University 88
Double Linked lists
• Deleting a node from the front of a doubly linked list
void delete_front()
{
node *temp;
if(head==NULL)
cout <<"No data inside\n";
else
{
temp = head;
head = head->next;
head->prev = NULL;
delete temp;
}
}
Injibara University 89
Double Linked lists
• Deleting any node using the search data from a doubly linked list
void delete_any(int y)
{
if(head==NULL)
cout <<"No data inside\n";
else
{
node *temp = head, *temp2;
while(temp->data != y)
{
temp2 = temp;
temp = temp->next;
}
temp2->next = temp->next;
temp->next->prev = temp2;
delete temp;
}
}
Injibara University 90
Double Linked lists
• Display the node from the doubly linked list in a forward manner
void display_forward()
{
node *temp;
if(head==NULL)
cout <<"No data inside\n";
else
{
temp = head;
while(temp!=NULL)
{
cout << temp->data << endl;
temp = temp->next;
}
}
}
Injibara University 91
Double Linked lists
• Display the node from the doubly linked list in a backward manner
void display_backward()
{
node *temp;
if(tail==NULL)
cout <<"No data inside\n";
else
{
temp = tail;
while(temp!=NULL)
{
cout << temp->data << endl;
temp = temp->prev;
}
}
}
Injibara University 92
Chapter Five
Stack and Queue

Injibara University 93
Stack
• A simple data structure, in which insertion and
deletion occur at the same end, is termed
(called) a stack. It is a LIFO (Last In First Out)
structure.
• Basic Stack Operations
– Push – Adds an item to the top of a stack.
– Pop – Removes an item from the top of the stack
and returns it to the user.
– Peek – Copies the top item of the stack and returns
it to the user; the item is not removed, hence the
stack is not altered.
Injibara University 94
Stack
• stack: a more restricted List with the following
constraints:
– Elements are stored by order of insertion from
"bottom" to "top“.
– Items are added to the top.
– Only the last element added onto the stack (the top
element) can be accessed or removed.

Injibara University 95
Stack

Injibara University 96
Stack
• Stacks in computer science
• the stack is one of the most important data structures in all of
computer science
– Function/method calls are placed onto a stack.
– Compilers use stacks to evaluate expressions.
– Stacks are great for reversing things, matching up related pairs of things, and
backtracking algorithms.
• Stack programming problems:
– Reverse letters in a string, reverse words in a line, or reverse a list of numbers.
– Find out whether a string is a palindrome. (Example: madam, lol, pop, radar)
– Examine a file to see if its braces { } and other operators match.
• Stack Application
– Reversing data
– Converting decimal to binary

Injibara University 97
Stack

Infix to postfix conversation


• Infix:-a natural way of expressing mathematical expression. There are other ways of representing the same
expression:
• Prefix: -AB
• Postfix: AB-
• Types of Expression
–The normal (or human) way of expressing mathematical expressions is called infix form, e.g. 4+5*5. However,
there are other ways of representing the same expression, either by writing all operators before their operands or
after them,
e.g.: 4 5 5 * +
+4*55
–This method is called Polish Notation (because this method was discovered by the Polish mathematician Jan
Lukasiewicz). 
–When the operators are written before their operands, it is called the prefix form
e.g. + 4 * 5 5
–When the operators come after their operands, it is called postfix form (suffix form or reverse polish notation)
e.g. 4 5 5 * + 
• The valuable aspect of RPN (Reverse Polish Notation or postfix )
–Parentheses are unnecessary
 
–Easy for a computer (compiler) to evaluate an arithmetic expression
Postfix (Reverse Polish Notation)

Injibara University 98
Stack
• Rules:
– Operands immediately go directly to output. Operators are pushed into the
stack (including parenthesis)
– Check to see if stack top operator is less than current operator
– If the top operator is less than, push the current operator onto stack
– If the top operator is greater than (or equal to) the current, pop top operator
and append on postfix notation, push current operator onto stack.
– If we encounter a right parenthesis, pop from stack until we get matching
left parenthesis.
• Do not output parenthesis.
– Precedence Priority of operators:
– Priority 4: ‘(‘ - only popped if a matching ‘)’ is found.
– Priority 3: All unary operators (-, sin, cosin, ….)/exponents
– Priority 2: / *
– Priority 1: + -
Injibara University 99
Stack
Exampl 1: infex  A + B * C - D / E
postfix = ABC*+DE/-

• Exampl 2:infex A * B - ( C + D ) + E
postfix =AB*CD+E+-
Example 3 : infex = a + b * c + ( d * e + f ) * g
postfix = abc*+de*f+g*+
Class A :

Injibara University 100


Stack
Postfix evaluation psuedo code
– Operand push operator
– Pop 2 operands , do the match
– Push result back onto stack
Example:
Exampl 1: postfix = ABC*+DE/-
infex  A + B * C - D / E

• Exampl 2:postfix =AB*CD+E+-


infex A * B - ( C + D ) + E
Class activity : 6 5 2 3 + 8 * + 3 + *

• Page-visited history in a Web browser


• To Undo and Redo in a text editor:
Injibara University 101
Stack
Array Implementation of a stack
– int f = - 1, r = - 1, s[50], n = 50;
– A stack can be implemented a static and dynamic data
structure. When we say a static, it is using array and when we
say dynamic, it is using linked list.
– Stack has at least the following operation:
– push an element to the top of the stack
– pop an element from the top of the stack
– display the content of the top element in the stack
– display the content of all elements in the stack forward
manner
– display the content of all elements in the stack backward
manner
Injibara University 102
Stack

• push an element to the top of the stack in an Array


void push()
{
int val;
if (r == n - 1)
cout << "Stack Overflow" << endl;
else
{
if (f == - 1)
f = 0;
cout << "Insert an element to push : " << endl;
cin>>val;
r++;
s[r] = val;
}
} Injibara University 103
Stack

• pop an element from the top of the stack in an array


void pop()
{
if (f == - 1 || f > r)
{
cout << "Stack Underflow ";
return ; //exist if the condition is true
}
else
{
cout << "Element popped off from stack is : " << s[r] << endl;
r--;
}
}
Injibara University 104
Stack
• display the content of the top element in the stack
in an array
void display_top()
{
if (f == - 1)
cout << "Stack is empty" << endl;
else
{
cout << "The top element in the Stack is : ";
cout << s[r] <<" ";
cout << endl;
}
}
Injibara University 105
Stack
• display the content of all elements in the stack forward manner in an
array
void display_forward()
{
if (f == - 1)
cout << "Stack is empty" << endl;
else
{
cout << "Stack elements are : ";
for (int i = f; i <= r; i++)
cout << s[i]<< " ";
cout << endl;
}
}
Injibara University 106
Stack
• display the content of all elements in the stack back manner in
an array
void display_backward()
{
if (r == - 1)
cout << "Stack is empty" << endl;
else
{
cout << "Stack elements are : ";
for (int i = r; i >= f; i--)
cout << s[i]<< " ";
cout << endl;
}
}
Injibara University 107
Stack
Linked list Implementation of a stack
• A stack can be implemented a static and dynamic data
structure. When we say a static, it is using array and when
we say dynamic, it is using linked list.
• Stack has at least the following operation:
• push an element to the top of the stack
• pop an element from the top of the stack
• display the content of the top element in the stack
• display the content of all elements in the stack forward
manner
• display the content of all elements in the stack backward
manner
Injibara University 108
Stack
struct node
{
int data;
struct node* next;
struct node* prev;
};
node *head = NULL, *tail = NULL;

Injibara University 109


Stack
• push an element to the top of the stack in a linked list
void insert_end(int x)
{
node* temp = new node;
temp->data = x;
temp->next = NULL;
temp->prev = NULL;
if (head == NULL)
head = tail = temp;
else
{
tail->next = temp;
temp->prev = tail;
tail = temp;
}
}
Injibara University 110
Stack
• pop an element from the top of the stack using a
linked list
void delete_end()
{
node *temp;
if(tail==NULL)
cout <<"No data inside\n";
else
{
temp = tail;
tail = tail->prev;
tail->next = NULL;
delete temp;
}
}
Injibara University 111
Stack

• display the content of the top element in the


stack using a linked list
void display_top()
{
node *temp;
if(tail==NULL)
cout << "No data inside\n";
else
{
cout << tail->data << endl;
}
}

Injibara University 112


Stack
• display the content of all elements in the stack in a forward
manner in a linked list
void display_forward()
{
node *temp;
if(head==NULL)
cout << "No data inside\n";
else
{
temp = head;
while(temp!=NULL)
{
cout << temp->data << endl;
temp = temp->next;
}
}
}
Injibara University 113
Stack
• display the content of all elements in the stack in a backward
manner in a linked list
void display_backward()
{
node *temp;
if(tail==NULL)
cout << "No data inside\n";
else
{
temp = tail;
while(temp!=NULL)
{
cout << temp->data << endl;
temp = temp->prev;
}
}
}
Injibara University 114
Queues
• a data structure that has access to its data at the front
and rear.
• operates on FIFO (Fast In First Out) basis.
• uses two pointers/indices to keep tack of
information/data.
• has two basic operations:
– enqueue - inserting data at the rear of the queue
– dequeue – removing data at the front of the queue  

Injibara University 115


Queues
Example:

Operation Content of queue


Enqueue(B) B
Enqueue(C) B, C
Dequeue() C
Enqueue(G) C, G
Enqueue (F) C, G, F
Dequeue() G, F
Enqueue(A) G, F, A
Dequeue() F, A

Injibara University 116


Queues
• Simple array implementation of enqueue and dequeue
operations
Analysis:
• Consider the following structure: int Num[MAX_SIZE];
• We need to have two integer variables that tell:
– the index of the front element
– the index of the rear element
• We also need an integer variable that tells:
– the total number of data in the queue
int FRONT =-1,REAR =-1;
int QUEUESIZE=0;
Injibara University 117
Queues

Injibara University 118


Queues
Implementation:
{
const int MAX_SIZE=100;
int FRONT =-1, REAR =-1; int x;
int QUEUESIZE = 0;
if(QUEUESIZE>0)
void enqueue(int x) {
{
if(Rear<MAX_SIZE-1)
x=Num[FRONT];
{ FRONT++;
REAR++;
Num[REAR]=x;
QUEUESIZE--;
QUEUESIZE++;  
if(FRONT = = -1)
FRONT++; }
} else
else
cout<<"Queue Overflow"; cout<<"Queue Underflow";
} return(x);
int dequeue()
}

Injibara University 119


Queues

• Application of Queues
– Print server- maintains a queue of print jobs
– Disk Driver- maintains a queue of disk input/output
requests 
– Task scheduler in multiprocessing system- maintains
priority queues of processes 
– Telephone calls in a busy environment –maintains a
queue of telephone calls
– Simulation of waiting line- maintains a queue of
persons
Injibara University 120
Chapter Six

TREE

Injibara University 121


Tree Terminologies
• Root: a node with out a parent.
–A
• Internal node: a node with at least one child.
– A, B, F, I, J
• External (leaf) node: a node without a child.
– C, D, E, H, K, L, M, G
• Ancestors of a node: parent, grandparent, grand-
grandparent, etc of a node.
– Ancestors of K A, F, I
• Descendants of a node: children, grandchildren, grand-
grandchildren etc of a node.
– Descendants of F H, I, J, K, L, M
• Depth of a node: number of ancestors or length of the path
from the root to the node.
– Depth of H 2
• Height of a tree: depth of the deepest node.
– 3

Injibara University 122


Binary Tree

• Binary tree: a tree in which each node has at most two children called left child
and right child
• Full binary tree: a binary tree where each node has either 0 or 2 children
• Balanced binary tree: a binary tree where each node except the leaf nodes has
left and right children and all the leaves are at the same level
• Complete binary tree: a binary tree in which the length from the root to any leaf
node is either h or h-1 where h is the height of the tree. The deepest level should
also be filled from left to right.

Injibara University 123


Binary Search Tree

• a binary tree that may be


empty, but if it is not empty it
satisfies the following.
– Every node has a key and no
two elements have the same
key.
– The keys in the right subtree are
larger than the keys in the root.
– The keys in the left subtree are
smaller than the keys in the
root.
– The left and the right subtrees
are also binary search trees.

Injibara University 124


Insertion
• When a node is inserted the definition of binary search tree
should be preserved.
• Suppose there is a binary search tree whose root node is
pointed by RootNodePtr and we want to insert a node (that
stores 17) pointed by InsNodePtr.
Case 1: There is no data in the tree (i.e. RootNodePtr is NULL)
– The node pointed by InsNodePtr should be made the root node.

Injibara University 125


Insertion
Case 2: There is data
– Search the appropriate position.
– Insert the node in that position

Injibara University 126


Insertion
• Implementation: else
  RNP = RNP->Left;
void InsertBST(Node *RNP, Node *INP) }
{ else
//RNP=RootNodePtr and INP=InsNodePtr {
int Inserted=0; if(RNP->Right = = NULL)
while(Inserted = =0) {
{ RNP->Right = INP;
if(RNP->Num > INP->Num) Inserted=1;
{ }
if(RNP->Left = = NULL) else
{ RNP = RNP->Right;
RNP->Left = INP; }
Inserted=1; }
} }

Injibara University 127


Traversing

• Binary search tree can be


traversed in three ways.
– Pre order traversal-
traversing binary tree in the
order of parent, left and
right.
– Inorder traversal -
traversing binary tree in the
order of left, parent and
right.
– Postorder traversal -
traversing binary tree in the
order of left, right and
parent.

Injibara University 128


Application of binary tree traversal

• Store values on leaf nodes and operators on


internal nodes
– Preorder traversal - used to generate mathematical expression in prefix
notation.
– Inorder traversal -used to generate mathematical expression in infix notation.
– Postorder traversal- used to generate mathematical expression in postfix
notation.

Injibara University 129


Application of binary tree traversal
void Inorder (Node *CurrNodePtr)
Function calls: {
• Preorder(RootNodePtr); if(CurrNodePtr ! = NULL)
• Inorder(RootNodePtr); {
• Postorder(RootNodePtr); Inorder(CurrNodePtr->Left);
  cout<< CurrNodePtr->Num;
Implementation:   // or any operation on the node
Inorder(CurrNodePtr->Right);
void Preorder (Node *CurrNodePtr)
}
{ }
if(CurrNodePtr ! = NULL)  
{ void Postorder (Node *CurrNodePtr)
{
cout<< CurrNodePtr->Num; // or any
if(CurrNodePtr ! = NULL)
operation on the node
{
Preorder(CurrNodePtr->Left); Postorder(CurrNodePtr->Left);
Preorder(CurrNodePtr->Right); Postorder(CurrNodePtr->Right);
} cout<< CurrNodePtr->Num; // or any
operation on the node
}
}
}
Injibara University 130
Searching
• To search a node (whose Num value is Number) in a binary search tree (whose root node is
pointed by RootNodePtr), one of the three traversal methods can be used.
Implementation:
bool SearchBST (Node *RNP, int x)
{
if(RNP = = NULL)
return(false);
else if(RNP->Num = = x)
return(true);
else if(RNP->Num > x)
return(SearchBST(RNP->Left, x));
else
return(SearchBST(RNP->Right, x));
}
Injibara University 131
Deletion
• To delete a node (whose Num value is N) from
binary search tree (whose root node is
pointed by RootNodePtr), four cases should be
considered.
– Case 1: Deleting a leaf node
– Case 2: Deleting a node having only one child
– Case 3: Deleting a node having two children
– Case 4: Deleting the root node

Injibara University 132


Assume

Injibara University 133


• Case 1: Deleting a leaf node (a node having
no child), e.g. 7

Injibara University 134


• Case 2: Deleting a node having only one child, e.g. 2
– If the deleted node is the left child of its parent and the deleted
node has only the left child, the left child of the deleted node is
made the left child of the parent of the deleted node.
– If the deleted node is the left child of its parent and the deleted
node has only the right child, the right child of the deleted node
is made the left child of the parent of the deleted node.
– If the deleted node is the right child of its parent and the node
to be deleted has only the left child, the left child of the deleted
node is made the right child of the parent of the deleted node.

– If the deleted node is the right child of its parent and the deleted
node has only the right child, the right child of the deleted node
is made the right child of the parent of the deleted node.
Injibara University 135
Injibara University 136
• Approach 2: Deletion by copying- the following is done
• Copy the node containing the largest element in the left
(or the smallest element in the right) to the node
containing the element to be deleted

Injibara University 137


• Case 3: Deleting a node having two children, e.g. 6
– Approach 1: Deletion by merging – one of the following is
done
– If the deleted node is the left child of its parent, one of the
following is done
• The left child of the deleted node is made the left child of the
parent of the deleted node, and
• The right child of the deleted node is made the right child of the
node containing largest element in the left of the deleted node
– OR
• The right child of the deleted node is made the left child of the
parent of the deleted node, and
• The left child of the deleted node is made the left child of the
node containing smallest element in the right of the deleted node
Injibara University 138
• If the deleted node is the right child of its parent, one of the
following is done
– The left child of the deleted node is made the right child of the
parent of the deleted node, and
– The right child of the deleted node is made the right child of the
node containing largest element in the left of the deleted node
• OR
– The right child of the deleted node is made the right child of the
parent of the deleted node, and
– The left child of the deleted node is made the left child of the
node containing smallest element in the right of the deleted node

Injibara University 139


Injibara University 140
Injibara University 141
• Approach 2: Deletion by copying- the following is done
• Copy the node containing the largest element in the left (or the smallest element
in the right) to the node containing the element to be deleted
• Delete the copied node

Injibara University 142


Injibara University 143
• Case 4: Deleting the root node, 10
Approach 1: Deletion by merging- one of the following is done 
• If the tree has only one node the root node pointer is made to
point to nothing (NULL)
• If the root node has left child
– the root node pointer is made to point to the left child
– the right child of the root node is made the right child of the node
containing the largest element in the left of the root node
• If root node has right child
– the root node pointer is made to point to the right child
– the left child of the root node is made the left child of the node
containing the smallest element in the right of the root node

Injibara University 144


Injibara University 145
• Approach 2: Deletion by copying- the following is done
• Copy the node containing the largest element in the left (or the smallest
element in the right) to the node containing the element to be deleted
• Delete the copied nod

Injibara University 146


Injibara University 147
Chapter Seven
Graph

Injibara University 148


Graph
• A graph is a mathematical structure consisting of a set of vertices and a set
of edges connecting the vertices.
• Formally: G = (V,E), where V is a set and E is subset of V X V .
• We can choose between two standard ways to represent a graph G = (V,E):
– as a collection of adjacency lists or
– as an adjacency matrix.
• Either way applies to both directed and undirected graphs.
• Because the adjacency-list representation provides a compact way to
represent 
– sparse graphs, those for which |E| is much less than |V|2, it is usually the method
of choice.
• We may prefer an adjacency-matrix representation, however,
– when the graph is dense, |E| is close to |V |2 or when we need to be able to tell
quickly if there is an edge connecting two given vertices.

Injibara University 149


Graph

Figure 1: Two representations of an undirected graph.


• An undirected graph G with 5 vertices and 7 edges.
• An adjacency-list representation of G.
• The adjacency-matrix representation of G.

Injibara University 150


Graph

Figure 2 Two representations of a directed graph.


• A directed graph G with 6 vertices and 8 edges.
• An adjacency-list representation of G.
• The adjacency-matrix representation of G.
Injibara University 151
Graph

• Directed and Undirected Graph


• G = (V,E) undirected if for all v,w € V : (v,w) € E <
== > (w, v) € E. Otherwise directed.
• A directed graph:
– G = (V,E) with vertex set V = {0,1,2,3,4,5, 6} and edge
set.
– E = {(0, 2), (0, 4), (0, 5), (1, 0), (2, 1), (2, 5), (3, 1), (3,
6), (4, 0), (4, 5), (6, 3), (6, 5)}

Injibara University 152


Graph

• Figure 3. directed graph


Injibara University 153
Graph

• Figure 4. An undirected graph


Injibara University 154
Graph

• Example of adjacency matrix data structure

Injibara University 155


Graph
• Examples of the adjacency list data structure Array
with one entry for each vertex v, which is a list of all
vertices adjacent to v.

Injibara University 156


Graph
• Sparse and dense graphs

Injibara University 157


Graph
• Weighted Graph and Unweighted Graph
• Weighted Graph
• A weighted graph is a graph that has a numerical level
associated with each edge e, called the weight of edge e.
• Edge weights can be integers, rational numbers, or real
numbers, which represent a concept such as distance,
connection costs.
• Unweighted Graph
– An unweighted graph is a graph that has not a
numerical level associated with each edge e.
Injibara University 158
Graph

Injibara University 159


Graph Traversals
• Graph Traversal is a strategy for visiting all vertices of a graph
– Breadth-first Search (BFS)
– Depth First Search (DFS)
• Breadth-first Search (BFS)
– Breadth-first search is one of the simplest algorithms for searching
a graph and the archetype for many important graph algorithms.
– Given a graph G = (V, E) and a distinguished source vertex s,
breadth-first search systematically explores the edges of G to
“discover” every vertex that is reachable from s.
– It computes the distance (smallest number of edges) from s to
each reachable vertex. It also produces a “breadth-first tree” with
root s that contains all reachable vertices.

Injibara University 160


• For any vertex v reachable from s, the simple path in the
breadth-first tree from s to v corresponds to a “shortest path”
from s to v in G, that is, a path containing the smallest number
of edges.
• Example of Breadth First Search

Injibara University 161


The algorithm works on both directed and undirected graphs

Injibara University 162


Shortest paths
• At the beginning of this section, we claimed that breadth-
first search finds the distance to each reachable vertex in a
graph G = (V, E) from a given source vertex s ε V.
• Define the shortest-path distance σ (s, v) from s to v as the
minimum number of edges in any path from vertex s to
vertex v if there is no path from s to v, then σ (s, v) =
infinity.
• We call a path of length σ (s, v) from s to v a shortest path
from s to v.
• Before showing that breadth-first search correctly
computes shortest path distances, we investigate an
important property of shortest-path distances.
Injibara University 163
Injibara University 164
Depth First Search
• The strategy followed by depth-first search is, as its name implies,
to
• Depth-first search explores edges out of the most recently
discovered vertex v that still has unexplored edges leaving it.
• Once all of v's edges have been explored, the search "backtracks"
to explore edges leaving the vertex from which v was discovered.
• This process continues until we have discovered all the vertices
that are reachable from the original source vertex.
• If any undiscovered vertices remain, then depth-first search
selects one of them as a new source, and it repeats the search
from that source.
• The algorithm repeats this entire process until it has discovered
every vertex.
Injibara University 165
• As in breadth-first search, whenever depth-first search discovers a vertex
v during a scan of the adjacency list of an already discovered vertex u, it
records this event by setting v's predecessor attribute v.π to u.
• Unlike breadth-first search, whose predecessor subgraph forms a tree,
the predecessor subgraph produced by a depth-first search may be
composed of several trees, because the search may repeat from multiple
sources.
• Therefore, we define the predecessor subgraph of a depth-first search
slightly differently from that of a breadth-first search
• The predecessor subgraph of a depth-first search forms a depth-first
forest comprising several depth-first trees.
• As in breadth-first search, depth-first search colors vertices during the
search to indicate their state.
• Each vertex is initially white, is grayed when it is discovered in the search,
and is blackened when it is finished, that is, when its adjacency list has
been examined completely.
Injibara University 166
• This technique guarantees that each vertex ends up in
exactly one depth-first tree, so that these trees are disjoint.
• Besides creating a depth-first forest, depth-first search also
timestamps each vertex. Each vertex v has two timestamps:
the first timestamp v.d records when v is first discovered
(and grayed), and the second timestamp v.f records when
the search finishes examining v's adjacency list (and
blackens v).
• These timestamps provide important information about
the structure of the graph and are generally helpful in
reasoning about the behavior of depth-first search.

Injibara University 167


• The procedure DFS below records when it
discovers vertex u in the attribute u:d and
when it finishes vertex u in the attribute u:f .
• These timestamps are integers between 1 and
2 |V|, since there is one discovery event and
one finishing event for each of the |V |
vertices. For every vertex u, u.d < u.f Vertex u
is WHITE before time u.d, GRAY between time
u.d and time u.f, and BLACK thereafter.
Injibara University 168
• pseudocode of depth-first-search algorithm
• The following pseudocode is the basic depth-first-search
algorithm. The input graph G may be undirected or directed. The
variable time is a global variable that we use for timestamping

Injibara University 169


Injibara University 170

You might also like