0% found this document useful (0 votes)
7 views52 pages

File 2

The document provides an overview of algorithm analysis and design, focusing on concepts such as running time, experimental studies, and theoretical analysis. It introduces recursion as a programming tool, detailing its key components and providing examples like the factorial method and binary search algorithm. Additionally, it discusses various types of algorithms, including simple recursive, backtracking, and dynamic programming algorithms.

Uploaded by

minanessim100
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views52 pages

File 2

The document provides an overview of algorithm analysis and design, focusing on concepts such as running time, experimental studies, and theoretical analysis. It introduces recursion as a programming tool, detailing its key components and providing examples like the factorial method and binary search algorithm. Additionally, it discusses various types of algorithms, including simple recursive, backtracking, and dynamic programming algorithms.

Uploaded by

minanessim100
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

Faculty of Computer and Artificial Intelligence

Sadat University

Analysis and Design of Algorithms (CS 302)

Lecture :2

“Introduction (Cont..)+ Recursion ”

Dr.Sara A Shehab
Analysis of
Algorithms

Input Algorithm Output

An algorithm is a step-by-step procedure for solving a


problem in a finite amount of time.
© 2004 Goodrich, Tamassia
Running Time
▪ Most algorithms transform input best case
average case
objects into output objects. worst case
120

▪ The running time of an 100

algorithm typically grows with

Running Time
80

the input size. 60

▪ Average case time is often 40

difficult to determine. 20

0
▪ We focus on the worst case 1000 2000 3000 4000
Input Size
running time.
◦ Easier to analyze
◦ Crucial to applications such as games,
finance and robotics
ANALYSIS OF ALGORITHMS 3
© 2004 Goodrich, Tamassia
Experimental Studies

▪ Write a program implementing 9000

the algorithm 8000

7000
▪ Run the program with inputs 6000

Time (ms)
of varying size and 5000

composition 4000

3000

▪ Use a method like 2000

System.currentTimeMillis() to get 1000

0
an accurate measure of the 0 50 100

actual running time Input Size

▪ Plot the results

ANALYSIS OF ALGORITHMS 4
© 2004 Goodrich, Tamassia
Limitations of Experiments
▪ It is necessary to implement the algorithm, which may
be difficult
▪ Results may not be indicative of the running time on
other inputs not included in the experiment.
▪ In order to compare two algorithms, the same hardware
and software environments must be used

© 2004 Goodrich, Tamassia ANALYSIS OF ALGORITHMS 5


Theoretical Analysis
▪ Uses a high-level description of the algorithm instead
of an implementation
▪ Characterizes running time as a function of the input
size, n.
▪ Takes into account all possible inputs
▪ Allows us to evaluate the speed of an algorithm
independent of the hardware/software environment

© 2004 Goodrich, Tamassia ANALYSIS OF ALGORITHMS 6


Pseudocode
▪ High-level description of Example: find max element
an algorithm of an array

▪ More structured than Algorithm arrayMax(A, n)


English prose Input array A of n integers
▪ Less detailed than a Output maximum element of A
program
currentMax  A[0]
▪ Preferred notation for
describing algorithms for i  1 to n − 1 do
if A[i]  currentMax then
▪ Hides program design
issues currentMax  A[i]
return currentMax

© 2004 Goodrich, Tamassia ANALYSIS OF ALGORITHMS 7


Pseudocode Details
Control flow Method call
◦ if … then … [else …] var.method (arg [, arg…])
◦ while … do …
Return value
◦ repeat … until …
return expression
◦ for … do …
◦ Indentation replaces braces Expressions
Assignment
Method declaration (like = in Java)
Algorithm method (arg [, arg…]) = Equality testing
Input … (like == in Java)
Output … n2 Superscripts and other
mathematical formatting
allowed

© 2004 Goodrich, Tamassia ANALYSIS OF ALGORITHMS 8


Pseudocode Details

© 2004 Goodrich, Tamassia


Pseudocode Details

© 2004 Goodrich, Tamassia


Pseudocode Details

© 2004 Goodrich, Tamassia


Pseudocode Details

© 2004 Goodrich, Tamassia


Pseudocode

© 2004 Goodrich, Tamassia


© 2004 Goodrich, Tamassia
Try this …..
Read 10 numbers from the user and display the
maximum number ?

Solution

© 2004 Goodrich, Tamassia


Types of Algorithms
◼ Algorithm types we will consider include:
◼ Simple recursive algorithms

◼ Backtracking algorithms

◼ Divide and conquer algorithms

◼ Dynamic programming algorithms

◼ Greedy algorithms

16
Recursion
Objectives

◼ Become familiar with the idea of recursion

◼ Learn to use recursion as a programming tool

◼ Become familiar with the binary search


algorithm as an example of recursion

◼ Become familiar with the merge sort


algorithm as an example of recursion
Overview

Recursion: a definition in terms of itself.

Recursion in algorithms:
◼ Natural approach to some (not all) problems

◼ A recursive algorithm uses itself to solve one or more

smaller identical problems

Recursion in Java:
◼ Recursive methods implement recursive algorithms

◼ A recursive method includes a call to itself


Key Components of a Recursive Algorithm Design

1. What is a smaller identical problem(s)?


Decomposition
2. How are the answers to smaller problems combined to form the
answer to the larger problem?
Composition
3. Which is the smallest problem that can be solved easily (without
further decomposition)?
Base/stopping case
Factorial (N!)

◼ N! = (N-1)! * N [for N > 1]


◼ 1! = 1
◼ 3!
= 2! * 3
= (1! * 2) * 3
=1*2*3
◼ Recursive design:
◼ Decomposition: (N-1)!
◼ Composition: * N
◼ Base case: 1!
factorial Method

public static int factorial(int n)


{
int fact;
if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; // composition
else // base case
fact = 1;

return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}

public static int factorial(int 2)


{
int fact;
if (n > 1)
fact = factorial(1) * 2;
else
fact = 1;
return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}

public static int factorial(int 2)


{
int fact;
if (n > 1)
fact = factorial(1) * 2;
else
fact = 1;
return fact;
}

public static int factorial(int 1)


{
int fact;
if (n > 1)
fact = factorial(n - 1) * n;
else
fact = 1;
return fact;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}

public static int factorial(int 2)


{
int fact;
if (n > 1)
fact = factorial(1) * 2;
else
fact = 1;
return fact;
}

public static int factorial(int 1)


{
int fact;
if (n > 1)
fact = factorial(n - 1) * n;
else
fact = 1;
return 1;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}

public static int factorial(int 2)


{
int fact;
if (n > 1)
fact = 1 * 2;
else
fact = 1;
return fact;
}

public static int factorial(int 1)


{
int fact;
if (n > 1)
fact = factorial(n - 1) * n;
else
fact = 1;
return 1;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = factorial(2) * 3;
else
fact = 1;
return fact;
}

public static int factorial(int 2)


{
int fact;
if (n > 1)
fact = 1 * 2;
else
fact = 1;
return 2;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = 2 * 3;
else
fact = 1;
return fact;
}

public static int factorial(int 2)


{
int fact;
if (n > 1)
fact = 1 * 2;
else
fact = 1;
return 2;
}
public static int factorial(int 3)
{
int fact;
if (n > 1)
fact = 2 * 3;
else
fact = 1;
return 6;
}
public static int factorial(int n)
{
int fact;
Execution Trace if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(decomposition) else // base case
fact = 1;
return fact;
}

factorial(4)

factorial(3) 4
public static int factorial(int n)
{
int fact;
Execution Trace if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(decomposition) else // base case
fact = 1;
return fact;
}

factorial(4)

factorial(3) 4

factorial(2) 3
public static int factorial(int n)
{
int fact;
Execution Trace if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(decomposition) else // base case
fact = 1;
return fact;
}

factorial(4)

factorial(3) 4

factorial(2) 3

factorial(1) 2
public static int factorial(int n)
{

Execution Trace int fact;


if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(composition) else // base case
fact = 1;
return fact;
}

factorial(4)
*
factorial(3) 4
*
factorial(2) 3

*
factorial(1)->1 2
public static int factorial(int n)
{

Execution Trace int fact;


if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(composition) else // base case
fact = 1;
return fact;
}

factorial(4)
*
factorial(3) 4
*
factorial(2)->2 3
public static int factorial(int n)
{

Execution Trace int fact;


if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(composition) else // base case
fact = 1;
return fact;
}

factorial(4)
*
factorial(3)->6 4
public static int factorial(int n)
{

Execution Trace int fact;


if (n > 1) // recursive case (decomposition)
fact = factorial(n – 1) * n; (composition)
(composition) else // base case
fact = 1;
return fact;
}

factorial(4)->24
Improved factorial Method

public static int factorial(int n)


{
int fact=1; // base case value

if (n > 1) // recursive case (decomposition)


fact = factorial(n – 1) * n; // composition
// else do nothing; base case

return fact;
}
Remember:Key to Successful Recursion

◼ if-else statement (or some other branching


statement)
◼ Some branches: recursive call
◼ "smaller" arguments or solve "smaller" versions of
the same task (decomposition)
◼ Combine the results (composition) [if necessary]
◼ Other branches: no recursive calls
◼ stopping cases or base cases
Template
… method(…)
{
if ( … )// base case
{
}
else // decomposition & composition
{
}
return … ; // if not void method
}
Template (only one base case)

… method(…)
{
… result = … ;//base case

if ( … ) // not base case


{ //decomposition & composition
result = …
}

return result;
}
Warning: Infinite Recursion May Cause a Stack
Overflow Error

◼ Infinite Recursion
◼ Problem not getting smaller (no/bad decomposition)

◼ Base case exists, but not reachable (bad base case

and/or decomposition)
◼ No base case

◼ Stack: keeps track of recursive calls by JVM (OS)


◼ Method begins: add data onto the stack

◼ Method ends: remove data from the stack

◼ Recursion never stops; stack eventually runs out of space


◼ Stack overflow error
Binary Search Algorithm

◼ Searching a list for a particular value


◼ sequential and binary are two common algorithms
◼ Sequential search (aka linear search):
◼ Not very efficient
◼ Easy to understand and program
◼ Binary search:
◼ more efficient than sequential
◼ but the list must be sorted first!
Why Is It Called "Binary" Search?

Compare sequential and binary search algorithms:


How many elements are eliminated from the list each
time a value is read from the list and it is not the
"target" value?

Sequential search: only one item


Binary search: half the list!

That is why it is called binary -


each unsuccessful test for the target value
reduces the remaining search list by 1/2.
private int search(int target, int first, int last)
Binary Search {
int location = -1; // not found
Method
if (first <= last) // range is not empty
◼ public
{
find(target) calls
int mid = (first + last)/2;
private
search(target,
if (target == a[mid])
first, last)
location = mid;
◼ returns the index of the else if (target < a[mid]) // first half
entry if the target value is location = search(target, first, mid - 1);
found or -1 if it is not else //(target > a[mid]) second half
found location = search(target, mid + 1, last);
◼ Compare it to the }
pseudocode for the
"name in the phone return location;
book" problem }
Where is the composition?
◼ If no items
◼ not found (-1)
◼ Else if target is in the middle
◼ middle location
◼ Else
◼ location found by search(first half) or search(second half)
Binary Search Example

target is 33
The array a looks like this:
Indices 0 1 2 3 4 5 6 7 8 9
Contents 5 7 9 13 32 33 42 54 56 88

mid = (0 + 9) / 2 (which is 4)
33 > a[mid] (that is, 33 > a[4])
So, if 33 is in the array, then 33 is one of:
5 6 7 8 9
33 42 54 56 88

Eliminated half of the remaining elements from


consideration because array elements are sorted.
Binary Search Example
target is 33
The array a looks like this:
0 1 2 3 4 5 6 7 8 9
Indexes
Contents 5 7 9 13 32 33 42 54 56 88

mid = (5 + 9) / 2 (which is 7)
33 < a[mid] (that is, 33 < a[7]) Eliminate
So, if 33 is in the array, then 33 is one of: half of the
5 6 remaining
33 42 elements

mid = (5 + 6) / 2 (which is 5)
33 == a[mid]
So we found 33 at index 5:
5
33
Binary vs. Sequential Search
◼ Binary Search
◼ log2N + 1 comparisons (worst case)

◼ Sequential/Linear Search
◼ N comparisons (worst case)

◼ Binary Search is faster but


◼ array is assumed to be sorted beforehand

◼ Faster searching algorithms for “non-sorted arrays”


◼ More sophisticated data structures than arrays

◼ Later courses
Recursive Versus Iterative Methods

All recursive algorithms/methods


can be rewritten without recursion.

◼ Iterative methods use loops instead of recursion

◼ Iterative methods generally run faster and use less


memory--less overhead in keeping track of method
calls
So When Should You Use Recursion?
◼ Solutions/algorithms for some problems are inherently
recursive
◼ iterative implementation could be more complicated

◼ When efficiency is less important


◼ it might make the code easier to understand

◼ Bottom line is about:


◼ Algorithm design

◼ Tradeoff between readability and efficiency

You might also like