introduction to algorithms

214
Algorithm Analysis & Data Algorithm Analysis & Data Structures Structures Jaideep Srivastava

Upload: venkatesh-iyer

Post on 17-May-2015

14.393 views

Category:

Technology


2 download

DESCRIPTION

The first things to look at in an algorithms course

TRANSCRIPT

Page 1: Introduction to Algorithms

Algorithm Analysis & Data Algorithm Analysis & Data StructuresStructures

Jaideep Srivastava

Page 2: Introduction to Algorithms

2

Schedule of topicsSchedule of topics

Lecture 1: Algorithm analysis Concept – what is it? Importance – why do it? Examples – lots of it Formalism

Lecture 2: Recursion Concept Examples

Lecture 3: Trees Concept & properties Tree algorithms

Page 3: Introduction to Algorithms

3

IntroductionIntroduction

A famous quote: Program = Algorithm + Data Structure. All of you have programmed; thus have already been

exposed to algorithms and data structure. Perhaps you didn't see them as separate entities; Perhaps you saw data structures as simple programming

constructs (provided by STL--standard template library). However, data structures are quite distinct from

algorithms, and very important in their own right.

Page 4: Introduction to Algorithms

Lecture 1 – Algorithm Analysis & Lecture 1 – Algorithm Analysis & ComplexityComplexity

Page 5: Introduction to Algorithms

5

ObjectivesObjectives The main focus of is to introduce you to a systematic

study of algorithms and data structures. The two guiding principles of the course are: abstraction

and formal analysis. Abstraction: We focus on topics that are broadly

applicable to a variety of problems. Analysis: We want a formal way to compare two objects

(data structures or algorithms). In particular, we will worry about "always correct"-ness,

and worst-case bounds on time and memory (space).

Page 6: Introduction to Algorithms

6

What is Algorithm Analysis ForWhat is Algorithm Analysis For

Foundations of Algorithm Analysis and Data Structures. Analysis:

How to predict an algorithm’s performance How well an algorithm scales up How to compare different algorithms for a problem

Data Structures How to efficiently store, access, manage data Data structures effect algorithm’s performance

Page 7: Introduction to Algorithms

7

Example AlgorithmsExample Algorithms Two algorithms for computing the Factorial Which one is better?

int factorial (int n) { if (n <= 1) return 1; else return n * factorial(n-1);}

int factorial (int n) { if (n<=1) return 1; else { fact = 1; for (k=2; k<=n; k++) fact *= k; return fact; }}

Page 8: Introduction to Algorithms

8

Examples of famous algorithmsExamples of famous algorithms

Constructions of Euclid Newton's root finding Fast Fourier Transform (signal processing) Compression (Huffman, Lempel-Ziv, GIF, MPEG) DES, RSA encryption (network security) Simplex algorithm for linear programming

(optimization) Shortest Path Algorithms (Dijkstra, Bellman-Ford) Error correcting codes (CDs, DVDs) TCP congestion control, IP routing (computer networks) Pattern matching (Genomics) Search Engines (www)

Page 9: Introduction to Algorithms

9

Role of Algorithms in Modern WorldRole of Algorithms in Modern World

Enormous amount of data Network traffic (telecom billing, monitoring) Database transactions (Sales, inventory) Scientific measurements (astrophysics,

geology) Sensor networks. RFID tags

Radio frequency identification (RFID) is a method of remotely storing and retrieving data using devices called RFID tags.

Bioinformatics (genome, protein bank)

Page 10: Introduction to Algorithms

10

A real-world ProblemA real-world Problem

Communication in the Internet Message (email, ftp) broken down into IP packets. Sender/receiver identified by IP address. The packets are routed through the Internet by special

computers called Routers. Each packet is stamped with its destination address, but

not the route. Because the Internet topology and network load is

constantly changing, routers must discover routes dynamically.

What should the Routing Table look like?

Page 11: Introduction to Algorithms

11

IP Prefixes and RoutingIP Prefixes and Routing

Each router is really a switch: it receives packets at several input ports, and appropriately sends them out to output ports.

Thus, for each packet, the router needs to transfer the packet to that output port that gets it closer to its destination.

Should each router keep a table: IP address x Output Port?

How big is this table? When a link or router fails, how much information would

need to be modified? A router typically forwards several million packets/sec!

Page 12: Introduction to Algorithms

12

Data StructuresData Structures

The IP packet forwarding is a Data Structure problem! Efficiency, scalability is very important.

Similarly, how does Google find the documents matching your query so fast?

Uses sophisticated algorithms to create index structures, which are just data structures.

Algorithms and data structures are ubiquitous. With the data glut created by the new technologies, the

need to organize, search, and update MASSIVE amounts of information FAST is more severe than ever before.

Page 13: Introduction to Algorithms

13

Algorithms to Process these DataAlgorithms to Process these Data

Which are the top K sellers? Correlation between time spent at a web site and

purchase amount? Which flows at a router account for > 1% traffic? Did source S send a packet in last s seconds? Send an alarm if any international arrival matches a

profile in the database Similarity matches against genome databases Etc.

Page 14: Introduction to Algorithms

14

Max Subsequence ProblemMax Subsequence Problem Given a sequence of integers A1, A2, …, An, find the maximum

possible value of a subsequence Ai, …, Aj. Numbers can be negative. You want a contiguous chunk with largest sum.

Example: -2, 11, -4, 13, -5, -2 The answer is 20 (subseq. A2 through A4).

We will discuss 4 different algorithms, with time complexities O(n3), O(n2), O(n log n), and O(n).

With n = 106, algorithm 1 may take > 10 years; algorithm 4 will take a fraction of a second!

Page 15: Introduction to Algorithms

15

int maxSum = 0;

for( int i = 0; i < a.size( ); i++ )

for( int j = i; j < a.size( ); j++ )

{int thisSum = 0;for( int k = i; k <= j; k+

+ )thisSum += a[ k ];

if( thisSum > maxSum )maxSum = thisSum;

}return maxSum;

Algorithm 1 for Max Subsequence SumAlgorithm 1 for Max Subsequence Sum

Given A1,…,An , find the maximum value of Ai+Ai+1+···+Aj

0 if the max value is negative

Time complexity: On3

)1(O

)( ijO

)1(O

)1(O

)1(O

))((1

n

ij

ijO ))((1

0

1

n

i

n

ij

ijO

Page 16: Introduction to Algorithms

16

Algorithm 2Algorithm 2

Idea: Given sum from i to j-1, we can compute the sum from i to j in constant time.

This eliminates one nested loop, and reduces the running time to O(n2).

into maxSum = 0;

for( int i = 0; i < a.size( ); i++ )

int thisSum = 0;for( int j = i; j < a.size( );

j++ ){ thisSum += a[ j ]; if( thisSum > maxSum

) maxSum =

thisSum;}

return maxSum;

Page 17: Introduction to Algorithms

17

Algorithm 3Algorithm 3

This algorithm uses divide-and-conquer paradigm.

Suppose we split the input sequence at midpoint.

The max subsequence is entirely in the left half, entirely in the right half, or it straddles the midpoint.

Example:left half | right half4 -3 5 -2 | -1 2 6 -2

Max in left is 6 (A1 through A3); max in right is 8 (A6 through A7). But straddling max is 11 (A1 thru A7).

Page 18: Introduction to Algorithms

18

Algorithm 3 (cont.)Algorithm 3 (cont.) Example:

left half | right half4 -3 5 -2 | -1 2 6 -2

Max subsequences in each half found by recursion. How do we find the straddling max subsequence? Key Observation:

Left half of the straddling sequence is the max subsequence ending with -2.

Right half is the max subsequence beginning with -1.

A linear scan lets us compute these in O(n) time.

Page 19: Introduction to Algorithms

19

Algorithm 3: AnalysisAlgorithm 3: Analysis

The divide and conquer is best analyzed through recurrence:

T(1) = 1T(n) = 2T(n/2) + O(n)

This recurrence solves to T(n) = O(n log n).

Page 20: Introduction to Algorithms

20

Algorithm 4Algorithm 4

Time complexity clearly O(n) But why does it work? I.e. proof of correctness.

2, 3, -2, 1, -5, 4, 1, -3, 4, -1, 2

int maxSum = 0, thisSum = 0;

for( int j = 0; j < a.size( ); j++ )

{thisSum += a[ j ];

if ( thisSum > maxSum )maxSum = thisSum;

else if ( thisSum < 0 )thisSum = 0;

}return maxSum;

}

Page 21: Introduction to Algorithms

21

Proof of CorrectnessProof of Correctness

Max subsequence cannot start or end at a negative Ai. More generally, the max subsequence cannot have a

prefix with a negative sum. Ex: -2 11 -4 13 -5 -2 Thus, if we ever find that Ai through Aj sums to < 0, then

we can advance i to j+1 Proof. Suppose j is the first index after i when the sum

becomes < 0 The max subsequence cannot start at any p between i

and j. Because Ai through Ap-1 is positive, so starting at i would have been even better.

Page 22: Introduction to Algorithms

22

Algorithm 4Algorithm 4

int maxSum = 0, thisSum = 0;

for( int j = 0; j < a.size( ); j++ ){

thisSum += a[ j ];

if ( thisSum > maxSum )maxSum = thisSum;

else if ( thisSum < 0 )thisSum = 0;

}return maxSum

• The algorithm resets whenever prefix is < 0. Otherwise, it forms new sums and updates maxSum in one pass.

Page 23: Introduction to Algorithms

23

Why Efficient Algorithms MatterWhy Efficient Algorithms Matter

Suppose N = 106

A PC can read/process N records in 1 sec. But if some algorithm does N*N computation, then it

takes 1M seconds = 11 days!!!

100 City Traveling Salesman Problem. A supercomputer checking 100 billion tours/sec still

requires 10100 years!

Fast factoring algorithms can break encryption schemes. Algorithms research determines what is safe code length. (> 100 digits)

Page 24: Introduction to Algorithms

24

How to Measure Algorithm PerformanceHow to Measure Algorithm Performance

What metric should be used to judge algorithms? Length of the program (lines of code) Ease of programming (bugs, maintenance) Memory required Running time

Running time is the dominant standard. Quantifiable and easy to compare Often the critical bottleneck

Page 25: Introduction to Algorithms

25

AbstractionAbstraction An algorithm may run differently depending on:

the hardware platform (PC, Cray, Sun) the programming language (C, Java, C++) the programmer (you, me, Bill Joy)

While different in detail, all hardware and programming models are equivalent in some sense: Turing machines.

It suffices to count basic operations.

Crude but valuable measure of algorithm’s performance as a function of input size.

Page 26: Introduction to Algorithms

26

Average, Best, and Worst-CaseAverage, Best, and Worst-Case

On which input instances should the algorithm’s performance be judged?

Average case: Real world distributions difficult to predict

Best case: Seems unrealistic

Worst case: Gives an absolute guarantee We will use the worst-case measure.

Page 27: Introduction to Algorithms

27

ExamplesExamples

Vector addition Z = A+Bfor (int i=0; i<n; i++)

Z[i] = A[i] + B[i];

T(n) = c n

Vector (inner) multiplication z =A*B

z = 0;for (int i=0; i<n; i++)

z = z + A[i]*B[i];

T(n) = c’ + c1 n

Page 28: Introduction to Algorithms

28

ExamplesExamples

Vector (outer) multiplication Z = A*BT

for (int i=0; i<n; i++) for (int j=0; j<n; j++) Z[i,j] = A[i] * B[j];T(n) = c2 n2;

A program does all the above T(n) = c0 + c1 n + c2 n2;

Page 29: Introduction to Algorithms

29

Simplifying the BoundSimplifying the Bound

T(n) = ck nk + ck-1 nk-1 + ck-2 nk-2 + … + c1 n + co

too complicated too many terms Difficult to compare two expressions, each

with 10 or 20 terms Do we really need that many terms?

Page 30: Introduction to Algorithms

30

SimplificationsSimplifications Keep just one term!

the fastest growing term (dominates the runtime) No constant coefficients are kept

Constant coefficients affected by machines, languages, etc.

Asymtotic behavior (as n gets large) is determined entirely by the leading term.

Example. T(n) = 10 n3 + n2 + 40n + 800 If n = 1,000, then T(n) = 10,001,040,800 error is 0.01% if we drop all but the n3 term

In an assembly line the slowest worker determines the throughput rate

Page 31: Introduction to Algorithms

31

SimplificationSimplification

Drop the constant coefficient Does not effect the relative order

Page 32: Introduction to Algorithms

32

SimplificationSimplification

The faster growing term (such as 2n) eventually will outgrow the slower growing terms (e.g., 1000 n) no matter what their coefficients!

Put another way, given a certain increase in allocated time, a higher order algorithm will not reap the benefit by solving much larger problem

Page 33: Introduction to Algorithms

33

T(n)n n n log n n2 n3 n4 n10 2n

10 .01s .03s .1s 1s 10s 10s 1s20 .02s .09s .4s 8s 160s 2.84h 1ms30 .03s .15s .9s s 810s 6.83d 1s40 .04s .21s 1.6s s 2.56ms 121d 18m50 .05s .28s s s 6.25ms 3.1y 13d

100 .1s .66s 10s 1ms 100ms 3171y 41013y103 1s 9.96s 1ms 1s 16.67m 3.171013y 3210283y104 s 130s 100ms 16.67m 115.7d 3.171023y105 s 1.66ms 10s 11.57d 3171y 3.171033y106 ms 19.92ms 16.67m 31.71y 3.17107y 3.171043y

Complexity and Tractability Complexity and Tractability

Assume the computer does 1 billion ops per sec.

Page 34: Introduction to Algorithms

34

log n n n log n n2 n3 2n

0 1 0 1 1 21 2 2 4 8 42 4 8 16 64 163 8 24 64 512 2564 16 64 256 4096 65,5365 32 160 1,024 32,768 4,294,967,296

0

10000

20000

30000

40000

50000

60000

70000

n1

10

100

1000

10000

100000

n

2n

n2

n log n

n

log n

log n

n

n log n

n2

n3

n32n

Page 35: Introduction to Algorithms

35

Another ViewAnother View

More resources (time and/or processing power) translate into large problems solved if complexity is low

T(n) Problem size solved in 103 sec

Problem size solved in 104 sec

Increase in Problem size

100n 10 100 10

1000n 1 10 10

5n2 14 45 3.2

N3 10 22 2.2

2n 10 13 1.3

Page 36: Introduction to Algorithms

36

T(n) keep one drop coef

3n2+4n+1 3 n2 n2

101 n2+102 101 n2 n2

15 n2+6n 15 n2 n2

a n2+bn+c a n2 n2

AsymptoticsAsymptotics

They all have the same “growth” rate

Page 37: Introduction to Algorithms

37

CaveatsCaveats

Follow the spirit, not the letter a 100n algorithm is more expensive

than n2 algorithm when n < 100 Other considerations:

a program used only a few times a program run on small data sets ease of coding, porting, maintenance memory requirements

Page 38: Introduction to Algorithms

38

Asymptotic NotationsAsymptotic Notations

Big-O, “bounded above by”: T(n) = O(f(n)) For some c and N, T(n) c·f(n) whenever n > N.

Big-Omega, “bounded below by”: T(n) = (f(n)) For some c>0 and N, T(n) c·f(n) whenever n > N. Same as f(n) = O(T(n)).

Big-Theta, “bounded above and below”: T(n) = (f(n)) T(n) = O(f(n)) and also T(n) = (f(n))

Little-o, “strictly bounded above”: T(n) = o(f(n)) T(n)/f(n) 0 as n

Page 39: Introduction to Algorithms

39

By PicturesBy Pictures

Big-Oh (most commonly used) bounded above

Big-Omega bounded below

Big-Theta exactly

Small-o not as expensive as ...

0N

0N

0N

Page 40: Introduction to Algorithms

40

Example Example

33

25

10

0

(?)(?)

nn

nn

nn

O

23 2)( nnnT

Page 41: Introduction to Algorithms

41

ExamplesExamples

)(log/1))/((!

)()(

)()()(

)1(cAsymptomic)(

1

0

11

321

21

1

niennn

rrninininnc

nf

ni

n

nini

kkni

ni

ni

kii

ki

Page 42: Introduction to Algorithms

42

Summary (Why O(n)?)Summary (Why O(n)?)

T(n) = ck nk + ck-1 nk-1 + ck-2 nk-2 + … + c1 n + co

Too complicated O(nk )

a single term with constant coefficient dropped

Much simpler, extra terms and coefficients do not matter asymptotically

Other criteria hard to quantify

Page 43: Introduction to Algorithms

43

Runtime AnalysisRuntime Analysis

Useful rules simple statements (read, write, assign)

O(1) (constant) simple operations (+ - * / == > >= < <=

O(1) sequence of simple statements/operations

rule of sums for, do, while loops

rules of products

Page 44: Introduction to Algorithms

44

Runtime Analysis (cont.)Runtime Analysis (cont.)

Two important rules Rule of sums

if you do a number of operations in sequence, the runtime is dominated by the most expensive operation

Rule of products if you repeat an operation a number of times, the

total runtime is the runtime of the operation multiplied by the iteration count

Page 45: Introduction to Algorithms

45

Runtime Analysis (cont.)Runtime Analysis (cont.)

if (cond) then O(1)body1 T1(n)

elsebody2 T2(n)

endif

T(n) = O(max (T1(n), T2(n))

Page 46: Introduction to Algorithms

46

Runtime Analysis (cont.)Runtime Analysis (cont.)

Method calls A calls B B calls C etc.

A sequence of operations when call sequences are flattenedT(n) = max(TA(n), TB(n), TC(n))

Page 47: Introduction to Algorithms

47

ExampleExample

for (i=1; i<n; i++)if A(i) > maxVal then

maxVal= A(i);maxPos= i;

Asymptotic Complexity: O(n)

Page 48: Introduction to Algorithms

48

ExampleExample

for (i=1; i<n-1; i++)for (j=n; j>= i+1; j--)

if (A(j-1) > A(j)) thentemp = A(j-1);A(j-1) = A(j);A(j) = tmp;

endifendfor

endfor

Asymptotic Complexity is O(n2)

Page 49: Introduction to Algorithms

49

Run Time for Recursive ProgramsRun Time for Recursive Programs

T(n) is defined recursively in terms of T(k), k<n The recurrence relations allow T(n) to be

“unwound” recursively into some base cases (e.g., T(0) or T(1)).

Examples: Factorial Hanoi towers

Page 50: Introduction to Algorithms

50

Example: Factorial Example: Factorial

int factorial (int n) { if (n<=1) return 1; else return n * factorial(n-1);}

factorial (n) = n*n-1*n-2* … *1

n * factorial(n-1)

n-1 * factorial(n-2)

n-2 * factorial(n-3)

2 *factorial(1)

T(n)

T(n-1)

T(n-2)

T(1)

)(

*)1(

*)1()1(

....

)3(

)2(

)1(

)(

nO

dnc

dnT

dddnT

ddnT

dnT

nT

Page 51: Introduction to Algorithms

51

Example: Factorial (cont.)Example: Factorial (cont.)

int factorial1(int n) { if (n<=1) return 1; else { fact = 1; for (k=2;k<=n;k++) fact *= k; return fact; }} Both algorithms are O(n).

)1(O

)1(O)(nO

Page 52: Introduction to Algorithms

52

Example: Hanoi TowersExample: Hanoi Towers

Hanoi(n,A,B,C) = Hanoi(n-1,A,C,B)+Hanoi(1,A,B,C)+Hanoi(n-

1,C,B,A)

)2(

)12...22(

)12...2()1(2

....

22)3(2

2)2(2

)1(2

)(

21

21

23

2

n

nn

nn

O

c

cT

cccnT

ccnT

cnT

nT

Page 53: Introduction to Algorithms

53

// Early-terminating version of selection sort bool sorted = false; !sorted &&

sorted = true;

else sorted = false; // out of order

Worst Case Best Case

template<class T>void SelectionSort(T a[], int n){

for (int size=n; (size>1); size--) { int pos = 0; // find largest for (int i = 1; i < size; i++) if (a[pos] <= a[i]) pos = i; Swap(a[pos], a[size - 1]); }}

Worst Case, Best Case, and Average CaseWorst Case, Best Case, and Average Case

Page 54: Introduction to Algorithms

54

T(N)=6N+4 : n0=4 and c=7, f(N)=N T(N)=6N+4 <= c f(N) = 7N for

N>=4 7N+4 = O(N) 15N+20 = O(N) N2=O(N)? N log N = O(N)? N log N = O(N2)?

T(N)f(N)

c f(N)

n0

T(N)=O(f(N))

N2 = O(N log N)?N10 = O(2N)?6N + 4 = W(N) ? 7N? N+4 ? N2? N log N?N log N = W(N2)?3 = O(1)1000000=O(1)Sum i = O(N)?

Page 55: Introduction to Algorithms

55

An Analogy: Cooking RecipesAn Analogy: Cooking Recipes Algorithms are detailed and precise instructions. Example: bake a chocolate mousse cake.

Convert raw ingredients into processed output. Hardware (PC, supercomputer vs. oven, stove) Pots, pans, pantry are data structures.

Interplay of hardware and algorithms Different recipes for oven, stove, microwave etc.

New advances. New models: clusters, Internet, workstations Microwave cooking, 5-minute recipes, refrigeration

Page 56: Introduction to Algorithms

Lecture 2 - RecursionLecture 2 - Recursion

Page 57: Introduction to Algorithms

57

What is Recursion?What is Recursion?

Recursion is when a function either directly or indirectly makes a call to itself.

Recursion is a powerful problem solving tool.

Many mathematical functions and algorithms are most easily expressed using recursion.

Page 58: Introduction to Algorithms

58

How does it work?How does it work?

Functions are implemented using an internal stack of activation records.

Each time a function is called a new activation record is pushed on the stack.

When a function returns, the stack is popped and the activation record of the calling method is on top of the stack.

Page 59: Introduction to Algorithms

59

How does it work? (cont.)How does it work? (cont.)

The function being called, and whose activation record is being pushed on the stack, can be different from the calling function (e.g., when main calls a function).

The function being called can be a different instance of the calling subprogram.

Each instance of the function has its own parameters and local variables.

Page 60: Introduction to Algorithms

60

ExampleExample

Many mathematical functions are defined recursively. For example, the factorial function:

N! = N * (N-1)! for N>0

0! = 1

We have defined factorial in terms of a smaller (or simpler) instance of itself.We must also define a base case or stopping condition.

Page 61: Introduction to Algorithms

Recursive Function CallRecursive Function Call

A recursive call is a function call in which the called function is the same as the one making the call.

We must avoid making an infinite

sequence of function calls (infinite recursion).

Page 62: Introduction to Algorithms

Finding a Recursive SolutionFinding a Recursive Solution

Each successive recursive call should bring you closer to a situation in which the answer is known. general (recursive) case

A case for which the answer is known (and can be expressed without recursion) is called a base case.

Page 63: Introduction to Algorithms

General format forGeneral format formany recursive functionsmany recursive functions

if (some conditions for which answer is known) // base case solution statement

else // general case recursive function call

Page 64: Introduction to Algorithms

Tail RecursionTail Recursion

Use only one recursive call at the end of a function

void tail (int i) { if (i > 0) { System.out.print( i+ “ ”); tail(i – 1); } }

void iterativetail(int i) {

for ( ; i > 0; i--)

System.out.print( i+ “ ”);

}

Page 65: Introduction to Algorithms

65

NonTail RecursionNonTail Recursion

void nonTail (int i) { if (i > 0) { nonTail(i – 1); System.out.print( i+ “ ”); nonTail(i – 1); } }

Page 66: Introduction to Algorithms

66

Indirect recursionIndirect recursionReceive( buffer )

while buffer is not filled upIf information is still incoming

get a char and store it in buffer;else exit();decode(buffer);

Decode(buffer)decode information in buffer;store(buffer);

Store(buffer)transfer information from buffer to file;receive(buffer);

Page 67: Introduction to Algorithms

67

Nested recursionNested recursion

h(n) { 0 if n=0h(n) ={ n if n>4 h(n) { h(2+h(2n)) if n <=4

Page 68: Introduction to Algorithms

Writing a recursive function to find Writing a recursive function to find n factorialn factorial

DISCUSSION

The function call Factorial(4) should have value 24, because that is 4 * 3 * 2 * 1 .

For a situation in which the answer is known, the value of 0! is 1.

So our base case could be along the lines of

if ( number == 0 ) return 1;

Page 69: Introduction to Algorithms

Writing a recursive function to find Writing a recursive function to find Factorial(n)Factorial(n)

Now for the general case . . .

The value of Factorial(n) can be written as n * the product of the numbers from (n - 1) to 1, that is,

n * (n - 1) * . . . * 1

or, n * Factorial(n - 1)

And notice that the recursive call Factorial(n - 1) gets us “closer” to the base case of Factorial(0).

Page 70: Introduction to Algorithms

70

Recursive Function Example: FactorialRecursive Function Example: Factorial

Problem: calculate n! (n factorial)

n! = 1 if n = 0 n! = 1 * 2 * 3 *...* n if n > 0

Recursively:

if n = 0, then n! = 1if n > 0, then n! = n * (n-1)!

Page 71: Introduction to Algorithms

71

Factorial FunctionFactorial Function

int RecFactorial( /* in */ int n)// Calculates n factorial, n! // Precondition: n is a non-negative// integer{ if (n <= 0) then

return 1 else

return n * RecFactorial(n-1)}

Page 72: Introduction to Algorithms

72

1int fact(int n)2{3 if (n <= 0) then4 return 1;

5 else6 return n*fact(n-1);

7 }

main(...) {

...

20 System.out.print( (fact(3));

...

returns 6 to main()

Page 73: Introduction to Algorithms

73

ExponentiationExponentiation

baseexponent

e.g. 53

Could be written as a function

Power(base, exp)

Page 74: Introduction to Algorithms

74

Can we write it recursively?Can we write it recursively?

be = b * b(e-1)

What’s the limiting case?

When e = 0 we have b0 which always equals?

1

Page 75: Introduction to Algorithms

75

Another Recursive FunctionAnother Recursive Function

1 function Power returnsa Num(base, exp)2 // Computes the value of BaseExp 3 // Pre: exp is a non-negative integer 4 if (exp = 0) then5 returns 16 else7 returns base * Power(base, exp-1)8 endif9 endfunction

Power xN = x * xN-1 for N>0 x0 = 1

main(...) {

...

20 cout << (Power(2,3));

...

Page 76: Introduction to Algorithms

76

A man has an infant male-female pair of rabbits in a hutch entirely surrounded by a wall. We wish to know how many rabbits can be bred from this pair in one year, if the nature of the rabbits is such that every month they breed one other male-female pair which begins to breed in the second month after their birth. Assume that no rabbits die during the year.

The PuzzleThe Puzzle

Page 77: Introduction to Algorithms

77

A Tree Diagram for Fibonacci’s PuzzleA Tree Diagram for Fibonacci’s Puzzle

Page 78: Introduction to Algorithms

78

ObservationsObservations

The number of rabbits at the beginning of any month equals the number of rabbits of the previous month plus the number of new pairs.

The number of new pairs at the beginning of a month equals the number of pairs two months ago.

One gets the sequence: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …233

Page 79: Introduction to Algorithms

79

Fibonacci sequenceFibonacci sequence

Recursive definitionf(1) = 1f(2) = 1f(n) = f(n-1) + f(n-2)

Page 80: Introduction to Algorithms

80

Fibonacci Number Sequence

if n = 1, then Fib(n) = 1if n = 2, then Fib(n) = 1if n > 2, then Fib(n) = Fib(n-2) + Fib(n-1)

Numbers in the series:1, 1, 2, 3, 5, 8, 13, 21, 34, ...

A More Complex Recursive FunctionA More Complex Recursive Function

Page 81: Introduction to Algorithms

81

Fibonacci Sequence FunctionFibonacci Sequence Function

function Fib returnsaNum (n)// Calculates the nth Fibonacci number // Precondition: N is a positive

integer if ((n = 1) OR (n = 2)) then returns 1 else returns Fib(n-2) + Fib(n-1) endifendfunction //Fibonacci

Page 82: Introduction to Algorithms

82

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Page 83: Introduction to Algorithms

83

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Page 84: Introduction to Algorithms

84

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns Fib(1) + Fib(2)

Page 85: Introduction to Algorithms

85

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(1): Fib returns 1

Page 86: Introduction to Algorithms

86

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns 1 + Fib(2)

Page 87: Introduction to Algorithms

87

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns 1 + Fib(2)

Fib(2): Fib returns 1

Page 88: Introduction to Algorithms

88

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns Fib(3) + Fib(4)

Fib(3): Fib returns 1 + 1

Page 89: Introduction to Algorithms

89

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Page 90: Introduction to Algorithms

90

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns Fib(2) + Fib(3)

Page 91: Introduction to Algorithms

91

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns Fib(2) + Fib(3)

Fib(2): Fib returns 1

Page 92: Introduction to Algorithms

92

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Page 93: Introduction to Algorithms

93

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns Fib(1) + Fib(2)

Page 94: Introduction to Algorithms

94

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns Fib(1) + Fib(2)

Fib(1): Fib returns 1

Page 95: Introduction to Algorithms

95

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns 1 + Fib(2)

Page 96: Introduction to Algorithms

96

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns 1 + Fib(2)

Fib(2): Fib returns 1

Page 97: Introduction to Algorithms

97

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + Fib(3)

Fib(3): Fib returns 1 + 1

Page 98: Introduction to Algorithms

98

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + Fib(4)

Fib(4): Fib returns 1 + 2

Page 99: Introduction to Algorithms

99

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- Fib(5)

Fib(5): Fib returns 2 + 3

Page 100: Introduction to Algorithms

100

Tracing with Multiple Recursive CallsTracing with Multiple Recursive Calls

Main Algorithm: answer <- 5

Page 101: Introduction to Algorithms

101

Fib(5)

Fib(3)Fib(4)

Fib(3) Fib(2)

Fib(2) Fib(1)

Fib(1) Fib(0)

Fib(1) Fib(0)

Fib(2) Fib(1)

Fib(1) Fib(0)

15 calls to Fib to find the 5th Fibonacci number!!!

Page 102: Introduction to Algorithms

102

Excessive Recursion-Fibonacci recursionExcessive Recursion-Fibonacci recursion

Int iterativeFib ( int n )if ( n < 2)

return n;else {

int i=2, tmp,current = 1, last=0;for ( ; i<=n; ++i) {

tmp=current;current+=last;last=tmp;}return current;

}}

Page 103: Introduction to Algorithms

103

Page 104: Introduction to Algorithms

104

Page 105: Introduction to Algorithms

105

Rules of RecursionRules of Recursion

First two fundamental rules of recursion:

Base cases: Always have at least one case that can be solved without using recursion.

Make progress: Any recursive call must make progress towards the base case.

Page 106: Introduction to Algorithms

106

Rules of RecursionRules of Recursion

Third fundamental rule of recursion:

“You gotta believe”: Always assume that the recursive call works.

Page 107: Introduction to Algorithms

107

Rules of RecursionRules of Recursion

Fourth fundamental rule of recursion:

Compound interest rule: Never duplicate work by solving the same instance of a problem in separate recursive calls.

Page 108: Introduction to Algorithms

108

Towers of HanoiTowers of Hanoi

The puzzle consisted of N disks and three poles: A (the source), B (the destination), and C (the spare)

Page 109: Introduction to Algorithms

109

Towers of HanoiTowers of Hanoi

B CA

Page 110: Introduction to Algorithms

110

Towers of HanoiTowers of Hanoi

B CA

Page 111: Introduction to Algorithms

111

Towers of HanoiTowers of Hanoi

B CA

Page 112: Introduction to Algorithms

112

Towers of HanoiTowers of Hanoi

B CA

Page 113: Introduction to Algorithms

113

Towers of HanoiTowers of Hanoi

B CA

Page 114: Introduction to Algorithms

114

Towers of HanoiTowers of Hanoi

B CA

Page 115: Introduction to Algorithms

115

Towers of HanoiTowers of Hanoi

B CA

Page 116: Introduction to Algorithms

116

Towers of HanoiTowers of Hanoi

B CA

Page 117: Introduction to Algorithms

117

Towers of HanoiTowers of Hanoi

A pseudocode description of the solution is:

Towers(Count, Source, Dest, Spare)

if (Count is 1)

Move the disk directly from Source to Dest

else

{

Solve Towers(Count-1, Source, Spare, Dest)

Solve Towers(1, Source, Dest, Spare)

Solve Towers(Count-1, Spare, Dest, Source)

}

Page 118: Introduction to Algorithms

118

Towers of HanoiTowers of Hanoi

void solveTowers( int count, char source, char dest, char spare){ if (count == 1) cout<<“Move disk from pole “ << source << " to pole " << destination <<endl; else { towers(count-1, source, spare, destination); towers(1, source, destination, spare); towers(count-1, spare, destination, source); }//end if}//end solveTowers

Page 119: Introduction to Algorithms

Recall that . . . Recall that . . .

Recursion occurs when a function calls itself (directly or indirectly).

Recursion can be used in place of iteration (looping).

Some functions can be written more easily using recursion.

Page 120: Introduction to Algorithms

120

Pascal TrianglePascal Triangle(Is this recursive?)(Is this recursive?)

Page 121: Introduction to Algorithms

121

Pascal TrianglePascal Triangle

The combinations of n items taken r at a time. For example:three items:    a    b    c

taken 2 at a time:    ab    ac    bc Thus there are three combinations of 3 items taken 2 at a

time. In General:    C(n,r) = n!/(r!(n-r)!)    Obviously you can

calculate C(n,r) using factorials.

Page 122: Introduction to Algorithms

122

Pascal TrianglePascal Triangle

This leads to Pascal Triangle:

n    0                            1             1                       1       1             2                    1     2      1             3                1     3      3     1             4            1     4      6      4    1             5        1     5      10     10    5    1

This can also be written:            r     0    1    2    3     4    5        n  0    1            1    1     1            2    1     2    1            3    1     3    3    1            4    1     4    6    4    1            5    1     5   10  10    5    1

Page 123: Introduction to Algorithms

123

Pascal TrianglePascal Triangle

Note from Pascal's Triangle that:    C(n,r) = C(n-1, r-1) + C(n-1,r)

This leads to the recurrence for nonnegative r and n,

C(n,r) =               1             if r = 0 or r = n,                           0             if r > n,                            C(n-1, r-1) + C(n-1,r)     otherwise.

Page 124: Introduction to Algorithms

124

Pascal TrianglePascal Triangle

This immediately leads to the recursive function for combinations:

 int C(int n, int r) {

  if((r == 0) || (r == n))     return 1;  else if(r > n)      return 0;  else       return C(n-1, r-1) + C(n-1, r);    }

Page 125: Introduction to Algorithms

What is the value of What is the value of rose(25)rose(25)??

int rose (int n){

if ( n == 1 ) // base casereturn 0;

else // general casereturn ( 1 + rose ( n / 2 ) );

}

Page 126: Introduction to Algorithms

Finding the value of Finding the value of rose(25)rose(25)

rose(25) the original call= 1 + rose(12) first recursive call= 1 + ( 1 + rose(6) ) second recursive call= 1 + ( 1 + ( 1 + rose(3) ) ) third recursive call= 1 + ( 1 + ( 1 + (1 + rose(1) ) ) ) fourth recursive call= 1 + 1 + 1 + 1 + 0= 4

Page 127: Introduction to Algorithms

Writing recursive functionsWriting recursive functions There must be at least one base case, and at least one

general (recursive) case. The general case should bring you “closer” to the base case.

The parameter(s) in the recursive call cannot all be the same as the formal parameters in the heading. Otherwise, infinite recursion would occur.

In function rose( ), the base case occurred when (n == 1) was true. The general case brought us a step closer to the base case, because in the general case the call was to rose(n/2), and the argument n/2 was closer to 1 (than n was).

Page 128: Introduction to Algorithms

Three-Question Method of verifyingThree-Question Method of verifying recursive functions recursive functions

Base-Case Question: Is there a nonrecursive way out of the function?

Smaller-Caller Question: Does each recursive function call involve a smaller case of the original problem leading to the base case?

General-Case Question: Assuming each recursive call works correctly, does the whole function work correctly?

Page 129: Introduction to Algorithms

Guidelines for writing recursive Guidelines for writing recursive functionsfunctions1. Get an exact definition of the problem to be solved.

2. Determine the size of the problem to be solved on this call to the function. On the initial call, the size of the whole problem is expressed by the actual parameter(s).

3. Identify and solve the base case(s) which have non-recursive solutions.

4. Identify and solve the general case(s) in terms of smaller (recursive) cases of the same problem.

Page 130: Introduction to Algorithms

struct ListType

{ int length ; // number of elements in the list

int info[ MAX_ITEMS ] ;

} ;

ListType list ;

struct ListTypestruct ListType

Page 131: Introduction to Algorithms

Recursive function to determine if value is in listRecursive function to determine if value is in listPROTOTYPE

bool ValueInList( ListType list , int value , int startIndex )

Already searched Needs to be searched

74 36 . . . 95

list[0] [1] [startIndex]

75 29 47 . . .

[length -1]

index of currentelement to examine

Page 132: Introduction to Algorithms

bool ValueInList ( ListType list , int value , int startIndex )

// Searches list for value between positions startIndex// and list.length-1{ if ( list.info[startIndex] == value ) // one base case

return true ; else if (startIndex == list.length -1 ) // another base case

return false ; else // general case

return ValueInList( list, value, startIndex + 1 ) ;}

132

Page 133: Introduction to Algorithms

““ Why use recursion?”Why use recursion?”

Many solutions could have been written without recursion, by using iteration instead. The iterative solution uses a loop, and the recursive solution uses an if statement.

However, for certain problems the recursive solution is the most natural solution. This often occurs when pointer variables are used.

Page 134: Introduction to Algorithms

134

When to Use RecursionWhen to Use Recursion

If the problem is recursive in nature therefore it is likely the a recursive algorithm will be preferable and will be less complex

If running times of recursive and non-recursive algorithms are hardly perceivable, recursive version is better

If both recursive and non-recursive algorithms have the same development complexity, a non-recursive version should be preferred

A third alternative in some problems is to use table-driven techniques

Sometimes we know that we will not use the only a few values of a particular function

If this is the case an implementation using a table would probably suffice and the performance will be better

int factorial[8] = {1, 1, 2, 6, 24, 120, 720, 5040};int factorial[8] = {1, 1, 2, 6, 24, 120, 720, 5040};

Page 135: Introduction to Algorithms

Use a recursive solution when:Use a recursive solution when:

The depth of recursive calls is relatively “shallow” compared to the size of the problem.

The recursive version does about the same amount of work as the nonrecursive version.

The recursive version is shorter and simpler than the nonrecursive solution.

SHALLOW DEPTH EFFICIENCY CLARITY

Page 136: Introduction to Algorithms

Lecture 3 – Binary TreesLecture 3 – Binary Trees

Page 137: Introduction to Algorithms

137

Why Trees?Why Trees?

Limitations of Arrays Linked lists Stacks Queues

Page 138: Introduction to Algorithms

138

Trees: Recursive DefinitionTrees: Recursive Definition

A tree is a collection of nodes. The collection can be empty, or consist of

a “root” node R. There is a “directed edge” from R to the

root of each subtree. The root of each subtree is a “child” of R. R is the “parent” of each subtree root.

Page 139: Introduction to Algorithms

139

Trees: Recursive Definition (cont.)Trees: Recursive Definition (cont.)

ROOT OF TREE T

T1 T2 T3 T4 T5

SUBTREES

Page 140: Introduction to Algorithms

140

Trees: An ExampleTrees: An Example

A

B C D E

FG H

I

Page 141: Introduction to Algorithms

141

Trees: More DefinitionsTrees: More Definitions

Nodes with no children are leaves: (C,E,F,H,I).

Nodes with the same parents are siblings: (B,C,D,E) and (G,H).

A path from node n to node m is the sequence of directed edges from n to m.

A length of a path is the number of edges in the path

Page 142: Introduction to Algorithms

142

Trees: More Definitions (cont.)Trees: More Definitions (cont.)

The level/depth of node n is the length of the path from the root to n. The level of the root is 0.

The height/depth of a tree is equal to the maximum level of a node in the tree.

The height of a node n is the length of the longest path from n to a leaf. The height of a leaf node is 0.

The height of a tree is equal to the height of the root node.

Page 143: Introduction to Algorithms

143

Binary Trees – A Informal DefinitionBinary Trees – A Informal Definition

A binary tree is a tree in which no node can have more than two children.

Each node has 0, 1, or 2 children In this case we can keep direct links to

the children:

struct TreeNode{ Object element; TreeNode *left_child; TreeNode *right_child;};

Page 144: Introduction to Algorithms

144

Binary Trees – Formal DefinitionBinary Trees – Formal Definition

A binary tree is a structure that contains no nodes, or is comprised of three disjoint sets of

nodes:a roota binary tree called its left subtreea binary tree called its right subtree

A binary tree that contains no nodes is called empty

Page 145: Introduction to Algorithms

145

Binary Trees: Recursive DefinitionBinary Trees: Recursive Definition

ROOT OF TREE T

T1 T2

SUBTREES

*left_child *right_child

Page 146: Introduction to Algorithms

146

Differences Between A Tree & A Binary TreeDifferences Between A Tree & A Binary Tree

No node in a binary tree may have more than 2 children, whereas there is no limit on the number of children of a node in a tree.

The subtrees of a binary tree are ordered; those of a tree are not ordered.

Page 147: Introduction to Algorithms

147

Differences Between A Tree & A Binary Tree Differences Between A Tree & A Binary Tree (cont.)(cont.) The subtrees of a binary tree are ordered; those

of a tree are not ordered

a

b

a

b

• Are different when viewed as binary trees

• Are the same when viewed as trees

Page 148: Introduction to Algorithms

148

Internal and External NodesInternal and External Nodes

Because in a binary tree all the nodes must have the same number of children we are forced to change the concepts slightly We say that all internal nodes have two children External nodes have no children

internal node

external node

Page 149: Introduction to Algorithms

149

Recursive definition of a Binary TreeRecursive definition of a Binary Tree Most of concepts related to binary trees can be explained

recursive For instance, A binary tree is:

An external node, or An internal node connected to a left binary tree and a

right binary tree (called left and right subtrees) In programming terms we can see that our definition for

a linked list (singly) can be modified to have two links from each node instead of one.

Page 150: Introduction to Algorithms

150

Property2: a unique path exists from the root to every other node

What is a binary tree? (cont.)What is a binary tree? (cont.)

Page 151: Introduction to Algorithms

151

Mathematical Properties of Binary TreesMathematical Properties of Binary Trees

Let's us look at some important mathematical properties of binary trees

A good understanding of these properties will help the understanding of the performance of algorithms that process trees

Some of the properties we'll describe relate also the structural properties of these trees. This is the case because performance characteristics of many algorithms depend on these structural properties and not only the number of nodes.

Page 152: Introduction to Algorithms

152

Minimum Number Of NodesMinimum Number Of Nodes

Minimum number of nodes in a binary tree whose height is h.

At least one node at each level.

minimum number of nodes is h + 1

Page 153: Introduction to Algorithms

153

Maximum Number Of NodesMaximum Number Of Nodes All possible nodes at first h levels are

present

Maximum number of nodes

= 1 + 2 + 4 + 8 + … + 2h = 2h+1 - 1

Page 154: Introduction to Algorithms

154

Number of Nodes & HeightNumber of Nodes & Height

Let n be the number of nodes in a binary tree whose height is h.

h + 1 <= n <= 2h+1 – 1 log2(n+1)-1 <= h <= n -1 The max heightmax height of a tree with N nodes is N - 1

(same as a linked list) The min heightmin height of a tree with N nodes is

log(N+1)-1

Page 155: Introduction to Algorithms

155

Relationship Between Number of Nodes Relationship Between Number of Nodes (Internal - External)(Internal - External) A binary tree with N internal nodes has N+1 external

nodes

Let's try to prove this using induction...

Page 156: Introduction to Algorithms

156

Number of edgesNumber of edges

A binary tree with N internal nodes has 2N edges

Let's try to prove this using induction...

Page 157: Introduction to Algorithms

157

Number of edgesNumber of edges

A binary tree with N nodes (internal and external) has N-1 edges

Let's try to prove this using induction...

Page 158: Introduction to Algorithms

158

Binary Tree RepresentationBinary Tree Representation

Array representation Linked representation

Page 159: Introduction to Algorithms

159

Binary TreesBinary Trees

Full binary tree : All internal nodes have two children.

Complete binary tree : All leaves have the same level All internal nodes have two children

Page 160: Introduction to Algorithms

160

Node Number Properties Node Number Properties

Parent of node i is node i/2 But node 1 is the root and has no parent

Left child of node i is node 2i But if 2i > n, node i has no left child

Right child of node i is node 2i+1 But if 2i+1 > n, node i has no right child

1

2 3

4 5 6 7

8 9 10 11 12 13 14 15

Complete binary tree

Page 161: Introduction to Algorithms

161

Full Binary Tree With n NodesFull Binary Tree With n Nodes Start with a complete binary tree that has at least

n nodes. Number the nodes as described earlier. The binary tree defined by the nodes numbered 1

through n is the unique n node full binary tree.

1

2 3

4 5 6 7

8 9 10 11 12 13 14 15Full binary tree with 11 nodes

Page 162: Introduction to Algorithms

162

Array RepresentationArray Representation

•Number the nodes using the numbering scheme for a full binary tree•Store the node numbered i in tree[i]

b

a

c

d e f g

h i j

1

2 3

4 5 6 7

8 9 10

tree[]0 5 10

a b c d e f g h i j1 2 3 4 6 7 8 9

Page 163: Introduction to Algorithms

163

Right-Skewed Binary TreeRight-Skewed Binary Tree

An n node binary tree needs an array whose length is between n+1 and 2n

If h = n-1 then skewed binary tree

a

b

1

3

c7

d15

tree[] 0 5 10

a - b - - - c - - - - - - -15d

Page 164: Introduction to Algorithms

164

Array Representation (cont.)Array Representation (cont.)

Each tree node is represented as a struct

Struct TreeNode {object element;

int child1; int child2; … int childn;};

Struct TreeNode tree[100];

Page 165: Introduction to Algorithms

165

Linked RepresentationLinked Representation

Each tree node is represented as an object whose data type is TreeNode

The space required by an n node binary tree is n * (space required by one node)

Page 166: Introduction to Algorithms

166

Trees: Linked representation Trees: Linked representation Implementation 1Implementation 1

struct TreeNode{ Object element; TreeNode *child1; TreeNode *child2; . . . TreeNode *childn;};

Each node contains a link to all of its children. This isn’t a good idea, because a node can have an arbitrary number of children!

Page 167: Introduction to Algorithms

167

struct TreeNode{ Object element; TreeNode *child1; TreeNode *sibling;};

Each node contain a link to its firstchild and a link to its next sibling. This isa better idea.

Trees: Linked representation Implementation 2

Page 168: Introduction to Algorithms

168

Implementation 2: ExampleImplementation 2: Example

/

The downward links are to the firstchild; the horizontal links are to thenext sibling.

A /

B

F /

C / D E /

G H /

I /

/

/

/

Page 169: Introduction to Algorithms

169

Binary TreesBinary Trees

A binary tree is a tree whose nodes have at most two offspring

Example struct nodeType { object element; struct nodeType *left, *right; }; struct nodeType *tree;

Page 170: Introduction to Algorithms

170

Linked Representation ExampleLinked Representation Example

a

cb

d

f

e

g

hleftChildelementrightChild

root

Page 171: Introduction to Algorithms

171

Some Binary Tree OperationsSome Binary Tree Operations

• Determine the height.• Determine the number of nodes.• Make a clone.• Determine if two binary trees are clones.• Display the binary tree.• Evaluate the arithmetic expression

represented by a binary tree.• Obtain the infix form of an expression.• Obtain the prefix form of an expression.• Obtain the postfix form of an expression.

Page 172: Introduction to Algorithms

CS122 Algorithms and Data StructuresCS122 Algorithms and Data Structures

Week 7: Binary Search Trees

Binary Expression Trees

Page 173: Introduction to Algorithms

173

Uses for Binary Trees…Uses for Binary Trees… -- -- Binary Search TreesBinary Search Trees Use for storing and retrieving information Insert, delete, and search faster than with a

linked list Idea: Store information in an ordered way (keys)

Page 174: Introduction to Algorithms

174

A Property of Binary Search TreesA Property of Binary Search Trees

The key of the root is larger than any key in the left subtree

The key of the root is smaller than any key in the right subtree

Note: Duplicated keys are not allowed

Page 175: Introduction to Algorithms

175

A Property of A Property of Binary Search TreeBinary Search Tree

ROOT OF TREE T

T1 T2

SUBTREES

*left_child *right_childX

All nodes in T1 havekeys < X.

All nodes in T2 havekeys > X.

Page 176: Introduction to Algorithms

176

Binary Search Trees in C++Binary Search Trees in C++

We will use two classes: The class BinaryNode simply constructs

individual nodes in the tree. The class BinarySearchTree maintains a

pointer to the root of the binary search tree and includes methods for inserting and removing nodes.

Page 177: Introduction to Algorithms

177

Search OperationSearch Operation

BinaryNode *search (const int &x, BinaryNode *t)

{

if ( t == NULL ) return NULL;

if (x == t->key) return t; // Match

if ( x < t->key )

return search( x, t->left );

else // t ->key < x

return search( x, t->right );

}

Page 178: Introduction to Algorithms

178

FindMin OperationFindMin Operation

BinaryNode* findMin (BinaryNode *t) {

if ( t == NULL )

return NULL;

if ( t -> left == NULL )

return t;

return findMin (t -> left);

}

This method returns a pointer to the node containing thesmallest element in the tree.

Page 179: Introduction to Algorithms

179

FindMax OperationFindMax Operation

BinaryNode* findMax (BinaryNode *t) {

if ( t == NULL )

return NULL;

if ( t -> right == NULL )

return t;

return findMax (t -> right);

}

This function returns a pointer to the node containing thelargest element in the tree.

Page 180: Introduction to Algorithms

180

Insert OperationInsert Operation

To insert X into a tree T, proceed down the tree as you would with a find. If X is found, do nothing. Otherwise insert X at the last spot on the path that has been traversed.

Page 181: Introduction to Algorithms

181

Insert Operation (cont.)Insert Operation (cont.)

void BinarySearchTree insert (const int &x, BinaryNode *&t) const

{

if (t == NULL)

t = new BinaryNode (x, NULL, NULL);

else if (x < t->key)

insert(x, t->left);

else if( t->key < x)

insert(x, t->right);

else

; // Duplicate entry; do nothing

}

Note the pointer t is passed using call by reference.

Page 182: Introduction to Algorithms

182

Removal OperationRemoval Operation

If the node to be removed is a leaf, it can be deleted immediately.

If the node has one child, the node can be deleted after its parent adjusts a link to bypass the deleted node.

Page 183: Introduction to Algorithms

183

If the node to be removed has two children, the general strategy is to replace the data of this node with the smallest key of the right subtree.

Then the node with the smallest data is now removed (this case is easy since this node cannot have two children).

Removal Operation (cont.)Removal Operation (cont.)

Page 184: Introduction to Algorithms

184

void remove (const int &x, BinaryNode* &t) const {

if ( t == NULL ) return; // key is not found; do nothing

if ( t->key == x) {

if( t->left != NULL && t->right != NULL ) { // Two children

t->key = findMin( t->right )->key;

remove( t->key, t->right );

}

else { // One child

BinaryNode *oldNode = t;

t = ( t->left != NULL ) ? t->left : t->right;

delete oldNode;

}

}

else { // Two recursive calls

if ( x < t->key ) remove( x, t->left );

else if( t->key < x ) remove( x, t->right );

}

}

Removal Operation (cont.)Removal Operation (cont.)

Page 185: Introduction to Algorithms

185

Deleting by mergingDeleting by merging

Page 186: Introduction to Algorithms

186

Deleting by mergingDeleting by merging

Page 187: Introduction to Algorithms

187

Deleting by copyingDeleting by copying

Page 188: Introduction to Algorithms

188

Balancing a binary treeBalancing a binary tree

A binary tree is height-balanced or simply balanced if the difference in height of both the subtrees is either zero or one

Perfectly balanced if all leaves are to be found on one level or two levels.

Page 189: Introduction to Algorithms

189

Balancing a binary treeBalancing a binary tree

Page 190: Introduction to Algorithms

190

AnalysisAnalysis

The running time of these operations is O(lv), where lv is the level of the node containing the accessed item.

What is the average level of the nodes in a binary search tree? It depends on how well balanced the tree is.

Page 191: Introduction to Algorithms

191

Average Level of NodesAverage Level of Nodes

10

5 20

1 8 13 34

Consider this very well-balanced binary search tree. What is thelevel of its leaf nodes?

1)(log so 122 21

0

NLN L

L

lv

lv

N=7

Data Order: 10, 5, 1, 8, 20, 13, 34

Page 192: Introduction to Algorithms

192

A Better AnalysisA Better Analysis

The analysis on the previous slide was for a particularly well-balanced binary search tree. However, not all binary search trees will be this well balanced.

In particular, binary search trees are created via insertions of data. Depending on the order of the data, various trees will emerge.

Page 193: Introduction to Algorithms

193

Effect of Data OrderEffect of Data Order

Obtained if data is 4, 3, 2 1

Obtained if data is 1, 2, 3, 4

Note in these cases the average depth of nodes is about N/2, not log(N)!

Page 194: Introduction to Algorithms

194

Depth of NodesDepth of Nodes

In the best case the depth will be about O(log N).

In the worst case, if the data are already ordered, the depth will be about O(N).

Page 195: Introduction to Algorithms

195

Effects of Data Order…Effects of Data Order…

So, if the input data are randomly ordered, what is the average depth of the nodes?

The analysis is beyond the scope of this course, but it can be shown that the average depth is O(log N), which is a very nice result.

Page 196: Introduction to Algorithms

196

SummarySummary

In this lecture we showed that, for an average binary search tree, the average depth of the nodes is O(log N). This is quite amazing, indicating that the bad situations, which are O(N), don’t occur very often.

However, for those who are still concerned about the very bad situations, we can try to “balance” the trees.

Page 197: Introduction to Algorithms

197

Uses for Binary Trees…Uses for Binary Trees…-- -- Binary Expression TreesBinary Expression Trees Binary trees are a good way to express

arithmetic expressions. The leaves are operands and the other nodes

are operators. The left and right subtrees of an operator

node represent subexpressions that must be evaluated before applying the operator at the root of the subtree.

Page 198: Introduction to Algorithms

198

Binary Expression Trees: ExamplesBinary Expression Trees: Examples

a + b+

a b

- a

-

a

(a + b) * (c – d) / (e + f)

/

+

a b

-

c d

+

e f

*

/

Page 199: Introduction to Algorithms

199

Merits of Binary Tree FormMerits of Binary Tree Form

Left and right operands are easy to visualize Code optimization algorithms work with the

binary tree form of an expression Simple recursive evaluation of expression

+

a b

-

c d

+

e f

*

/

Page 200: Introduction to Algorithms

Levels Indicate PrecedenceLevels Indicate Precedence

The levels of the nodes in the tree indicate their relative precedence of evaluation (we do not need parentheses to indicate precedence).

Operations at lower levels of the tree are evaluated later than those at higher levels.

The operation at the root is always the last operation performed.

Page 201: Introduction to Algorithms

A Binary Expression TreeA Binary Expression Tree

What value does it have?

( 4 + 2 ) * 3 = 18

‘*’

‘+’

‘4’

‘3’

‘2’

Page 202: Introduction to Algorithms

Inorder Traversal: (A + H) / (M - Y)Inorder Traversal: (A + H) / (M - Y)

‘/’

‘+’

‘A’ ‘H’

‘-’

‘M’ ‘Y’

tree

Print left subtree first Print right subtree last

Print second

Page 203: Introduction to Algorithms

203

Inorder Traversal (cont.)Inorder Traversal (cont.)

a

+

*

b c

+

*

+ g

*

d e

f

Inorder traversal yields: (a + (b * c)) + (((d * e) + f) * g)

Page 204: Introduction to Algorithms

Preorder Traversal: / + A H - M YPreorder Traversal: / + A H - M Y

‘/’

‘+’

‘A’ ‘H’

‘-’

‘M’ ‘Y’

tree

Print left subtree second Print right subtree last

Print first

Page 205: Introduction to Algorithms

205

Preorder Traversal (cont.)Preorder Traversal (cont.)

a

+

*

b c

+

*

+ g

*

d e

f

Preorder traversal yields: (+ (+ a (* b c)) (* (+ (* d e) f) g))

Page 206: Introduction to Algorithms

‘/’

‘+’

‘A’ ‘H’

‘-’

‘M’ ‘Y’

tree

Print left subtree first Print right subtree second

Print last

Postorder Traversal: A H + M Y - /

Page 207: Introduction to Algorithms

207

Postorder Traversal (cont.)Postorder Traversal (cont.)

a

+

*

b c

+

*

+ g

*

d e

f

Postorder traversal yields: a b c * + d e * f + g * +

Page 208: Introduction to Algorithms

208

Traversals and ExpressionsTraversals and Expressions

Note that the postorder traversal produces the postfix representation of the expression.

Inorder traversal produces the infix representation of the expression.

Preorder traversal produces a representation that is the same as the way that the programming language Lisp processes arithmetic expressions!

Page 209: Introduction to Algorithms

209

Constructing an Expression TreeConstructing an Expression Tree

There is a simple O(N) stack-based algorithm to convert a postfix expression into an expression tree.

Recall we also have an algorithm to convert an infix expression into postfix, so we can also convert an infix expression into an expression tree without difficulty (in O(N) time).

Page 210: Introduction to Algorithms

210

Expression Tree AlgorithmExpression Tree Algorithm

Read the postfix expression one symbol at at time: If the symbol is an operand, create a one-node tree

and push a pointer to it onto the stack. If the symbol is an operator, pop two tree pointers T1

and T2 from the stack, and form a new tree whose root is the operator, and whose children are T1 and T2.

Push the new tree pointer on the stack.

Page 211: Introduction to Algorithms

211

ExampleExample

a b + :

Note: These stacks are depicted horizontally.

a b

+

ba

Page 212: Introduction to Algorithms

212

ExampleExample

a b + c d e + :

+

ba

c d e

+

ba

c

d e

+

Page 213: Introduction to Algorithms

213

ExampleExample

a b + c d e + * :

+

ba c

d e

+

*

Page 214: Introduction to Algorithms

214

ExampleExample

a b + c d e + * * :

+

ba c

d e

+

*

*