COSC 1P03 Data Structures and Abstraction 8.1 Recursion Recursion Recursion Recursion Recursion Recursion Recursion Recursion Recursion Just be thankful

  • View
    218

  • Download
    0

Embed Size (px)

Text of COSC 1P03 Data Structures and Abstraction 8.1 Recursion Recursion Recursion Recursion Recursion...

Chapter 8 Recursion

COSC 1P03Data Structures and Abstraction8.#Koch Curve

Order 0Order 1Order 2Order 3COSC 1P03Data Structures and Abstraction8.#Memory Managementrequirementsnew storage for locals & parametersreturn pointcould be called from more than one placeallocate storage on demandat method callactivation record (AR)block of storage for method invocation to userepresents method activationstorage for all local variables, parameters, return point and otherallocated at call, freed at returnmethod executionnote: locals become undefined at each callCOSC 1P03Data Structures and Abstraction8.#Principles and RulesBase cases: you must always have some base cases, which can be solved without recursion.Solving the recursive function f(x) = 2f(x-1) + x2Example 1

Note a base case generally kills the recursion by not allowing future recursive calls.int f (int x) { if (x == 0) return 0 else return 2*f(x-1)+x*xBase Case: since at this point recursion is not needed to determine a return value.COSC 1P03Data Structures and Abstraction8.#PrintList (node ptr){ if (ptr != null) { print(ptr.data); PrintList(ptr.next); }} Example 2If statement prevents recursive part from being called.DABCHeadPrinciples and Rules.COSC 1P03Data Structures and Abstraction8.#Principles and Rules..Making progress: For the cases that are solved recursively, the recursive call must always be to a case that makes progress toward a base case.int f (int x) { if (x == 0) return 0 else return 2*f(x-1)+x*xPrintList (node ptr){ if (ptr != null) { print(ptr.data); PrintList(ptr.next); }} X is reduced toward the base case.We assume that ptr.next will take us toward the end of the list, hence a null pointer.COSC 1P03Data Structures and Abstraction8.#Method Executionmethod invocationsuspend methodpass parametersexecute called methodreactivate calling methodstorage for local variables & formal parametersseparate storage for each invocation?if not one invocation interferes with another poor abstractionsomewhat more complex than original memory modelCOSC 1P03Data Structures and Abstraction8.#Image Scanprivate int cellCount ( int r, int c ) {if ( r=h | c=w ) {return 0;}else {if ( image[r][c] == ' ' | image[r][c] == '*' ) {return 0;}else {image[r][c] = '*';return cellCount(r+1,c-1) + cellCount(r+1,c ) + cellCount(r+1,c+1) + cellCount(r ,c-1) + 1 + // (r,c) cellCount(r ,c+1) + cellCount(r-1,c-1) + cellCount(r-1,c ) + cellCount(r-1,c+1);};};};// cellCountFirst base case, if we hit the edge of the image.Second base case, if we find a space or a cell we have already processed.Else we found a cell which has not been process, so mark it as processed *.Count the cell found as +1Recurse to each of the adjacent cells.As each cell is evaluated, the count is returned.Progress toward the base case is based on the assumption that the cells in the cluster are finite, thus have an edge.COSC 1P03Data Structures and Abstraction8.#

COSC 1P03Data Structures and Abstraction8.#

COSC 1P03Data Structures and Abstraction8.#What the Machine does - Call ReturnWhen a method returns:The call frame is removed from the stackLocal variables of previous AR are restored.System continues from this returned state.Since a call frame stores a system state, we can say a history is also stored. Previous values, Previous locations. History is a state of suspended animation which can be woke at the correct time.COSC 1P03Data Structures and Abstraction8.#We wish to print the list forward and backward using recursion.PrintList (node ptr){ if (ptr != null) { print(ptr.data); PrintList(ptr.next); print(ptr.data); }} DABCHeadThe result of the code would be:A B C D D C B AExample of RecursionCOSC 1P03Data Structures and Abstraction8.#Ptr.Next => Node CPtr.Next => Node D DABCHeadPrintList (node ptr){ if (ptr != null) { print(ptr.data); PrintList(ptr.next); print(ptr.data); }} Entry Ptr => Node AABCDDCBAPtr.Next => Node BPtr.Next => NullNotice that B C & D are simply a sub-problem of the entire listCOSC 1P03Data Structures and Abstraction8.#Pattern of Recursive ExecutionARs for recursive methods handled same as non-recursivemay be more than one AR for the same method on the stacktop AR is for the currently executing invocation of the methode.g. factorialinitial call (factorial(n))say n=3first invocation beginsfirst recursive call2 more recursive callsjust before first returnafter first return2 more returnsreturn to mainunderstanding recursionabstractionCOSC 1P03Data Structures and Abstraction8.#Recognizing Recursive ProblemsYou have the potential for a recursive solution ifA mathematical function is defined recursively.Mathematical induction is used to prove the function (data structure).The problem is composed of sub-problems with the same properties as the main problem.Is there a trivial case?Does the sub-problem tend toward the trivial case?Onion TestLook at an onionRemove the outer layerDoes it still look like an Onion?Yes, recursion may be possible.No, Iterative solution needed.COSC 1P03Data Structures and Abstraction8.#Recursive Algorithmstermination requirementstrivial casereductionproof reduction leads to trivial caseproof of terminationfactorialtrivial case: n=0reduction: factorial(n-1)proofFibonacci numberstrivial cases: n=0, n=1reduction: fibonacci(n-1), fibonacci(n-2)proof COSC 1P03Data Structures and Abstraction8.#Recursion vs Iterationiterative algorithm always existsconsider machine codecan translate recursive algorithm into iterativereplace byloopstack of statee.g. tail recursiondont even need stackiterative factorialdifferent point of viewe.g. Fibonacci numbersgenerate in sequenceCOSC 1P03Data Structures and Abstraction8.#ExamplesKoch curvespace filling curvetransformation of a straight lineorder & lengthrecursion4 Koch curves of lower orderKoch snowflakeimage recognitione.g. MRIimagearray of cellslocate single connected areaneighborsavoiding duplicationalgorithm and outputSite with lots of good examplesCOSC 1P03Data Structures and Abstraction8.#Recursion v.s. Iteration.comparisonfactorial O(n) vs O(n)Fibonacci O(n) vs O(2n) See next slidepenalties for recursionspacetimeadvantages of recursionrecursive algorithm sometimes simplerprogrammer productivitymaintenancebasic rulelook for iterative solutionwhen not easily found or complex consider recursionCOSC 1P03Data Structures and Abstraction8.#Fibonacci Numbersn = 3 the first instance of fib calculates:fib(n-1) ==> [fib(2) and [fib(n-2) ==> fib(1)]] line 1fib(2) results in instancesfib(1) and fib(0) line 2Notice: Instance of fib(1) is now known form line 2But fib(1) in line 1 has yet to be processedSo fib(1) is recalculated.Results in:Slow algorithmsIncreases the magnitude unnecessarily.COSC 1P03Data Structures and Abstraction8.#Call Tree for fib(5)http://www2.hig.no/~algmet/animate.html

COSC 1P03Data Structures and Abstraction8.#Design RuleDesign rule: Assume that all recursive calls work.In general the machine uses its own stack to organize the calls.Very difficult to trace the calls.Important to ensure the code adheres to the first two principles, this rule then takes care of itself.

COSC 1P03Data Structures and Abstraction8.#Applying of Recursionindicatorsvariety of casestrivial casecan express general case in terms of reductione.g. recursive structuressequentially-linked structureshead & tailsequential traversaltrivial case empty listreduction apply to tailLISPCOSC 1P03Data Structures and Abstraction8.#

COSC 1P03Data Structures and Abstraction8.#

COSC 1P03Data Structures and Abstraction8.#

COSC 1P03Data Structures and Abstraction8.#Koch Curve../**This method draws a Koch curve of specified order and length. ** **@paramorderorder of curve **@paramlenlength of curve.*/ private void koch ( int order, double len ) {if ( order == 0 ) {yertle.forward(len);}else {koch(order-1,len/3);yertle.left(Math.PI/3);koch(order-1,len/3);yertle.right(2*Math.PI/3);koch(order-1,len/3);yertle.left(Math.PI/3);koch(order-1,len/3);};};// kochOrder 0 curve is the base case, so draw a straight line. Notice no recursion.A line segment in a Koch curve is represented by 4 unitsEach of those line segments are again represented by 4 line segments, Recursing allows these sub-segments to be drawn.As we recurse the order is reduced tending toward the base case.COSC 1P03Data Structures and Abstraction8.#The EndCOSC 1P03Data Structures and Abstraction8.#n!=1 ( 2 ( ( (n-1) ( n

n!=1if n = 0

n ( (n-1)!if n > 0

0, 1, 1, 2, 3, 5, 8, 13, 21,

fn=nif n ( 1

fn-1 + fn-2if n > 1

Statement:WhileStatement

WhileStatement:while ( Expression ) Statement

1. storage for AR is allocated

2. actual parameters are evaluated and copied to storage for local parameters in AR

3. return address is copied to AR

4. method execution begins (accessing AR for parameters and locals)

5. return value (if any) is evaluated

6. return address is accessed

7. AR is deallocated

8. calling method continues (at return address) using return value (if any)

Figure 8.3 Steps in method execution

calls: A(B(C(D

returns: D(C(B(A

Figure 8.4 Memory allocation

_1018876380.doc

main memory

code

stack

heap

(a)

_1018707333.doc

:

out.writeLong(factorial(n));

:

private long factorial ( int n ) {

longresult;

if ( n == 0 ) {

result = 1;

}

else {

result = n * factorial(n-1);

};

return result;

};// factorial

n

3

(b)

_1018707372.doc

:

out.writeLong(factor