Presentation is loading. Please wait.

Presentation is loading. Please wait.

Winter 2006CISC121 - Prof. McLeod1 Stuff No stuff today!

Similar presentations


Presentation on theme: "Winter 2006CISC121 - Prof. McLeod1 Stuff No stuff today!"— Presentation transcript:

1 Winter 2006CISC121 - Prof. McLeod1 Stuff No stuff today!

2 Winter 2006CISC121 - Prof. McLeod2 Last Time Looked at some sorting animations, followed by a closer look at Bubble sort. Determined the complexity of the simple sorts, by analysis and measurement. Looked at searching – sequential search and binary search.

3 Winter 2006CISC121 - Prof. McLeod3 Today Left from last time – the complexity of binary search. Start Recursion!

4 Winter 2006CISC121 - Prof. McLeod4 Binary Search – Cont. public int binSearch (int[] A, int key) { int lo = 0; int hi = A.length - 1; int mid = (lo + hi) / 2; while (lo <= hi) { if (key < A[mid]) hi = mid - 1; else if (A[mid] < key) lo = mid + 1; else return mid; mid = (lo + hi) / 2; } return -1; }

5 Winter 2006CISC121 - Prof. McLeod5 Complexity of Binary Search For the best case, the element matches right at the middle of the array, and the loop only executes once. For the worst case, key will not be found and the maximum number of loops will occur. Note that the loop will execute until there is only one element left that does not match. Each time through the loop the number of elements left is halved, giving the progression below for the number of elements:

6 Winter 2006CISC121 - Prof. McLeod6 Complexity of Binary Search, Cont. Number of elements to be searched - progression: The last comparison is for n/2 m, when the number of elements is one (worst case). So, n/2 m = 1, or n = 2 m. Or, m = log 2 (n). So, the algorithm is O(log(n)) for the worst case.

7 Winter 2006CISC121 - Prof. McLeod7 Binary Search - Cont. Binary search at O(log(n)) is much better than sequential at O(n). Major reason to sort datasets!

8 Winter 2006CISC121 - Prof. McLeod8 A Caution on the Use of “Big O” Big O notation usually ignores the constant c. The constant’s magnitude depends on external factors (hardware, OS, etc.) For example, algorithm A has the number of operations = 10 8 n, and algorithm B has the form 10n 2. A is then O(n), and B is O(n 2 ). Based on this alone, A would be chosen over B. But, if c is considered, B would be faster for n up to 10 7 - which is a very large dataset! So, in this case, B would be preferred over A, in spite of the Big O notation.

9 Winter 2006CISC121 - Prof. McLeod9 A Caution on the Use of “Big O” – Cont. For “mission critical” algorithm comparison, nothing beats experiments where actual times are measured. When measuring times, keep everything else constant, just change the algorithm (same hardware, OS, type of data, etc.).

10 Winter 2006CISC121 - Prof. McLeod10 Recursion An advanced programming technique that can be used with any language that supports procedure or function calls (or “methods!”). Advanced sorting algorithms, like Quicksort, use recursion. We will also look at how to analyze the complexity of recursive algorithms.

11 Winter 2006CISC121 - Prof. McLeod11 Recursion, Cont. Most simply defined as when a method “calls itself” as part of its normal operation. For example: public int factorial (int n) { if (n == 0) return 1; else return n * factorial(n – 1); } // end factorial method

12 Winter 2006CISC121 - Prof. McLeod12 Recursion, Cont. Start by considering recursive definitions: A recursive definition has two parts: –The “anchor”, “ground case” or “stopping case” supplies all the basic elements out of which all other elements of the set are constructed. This part is not recursive. –The second part consists of the rules that determine how all other elements are constructed. It will define a new element starting from an element that has already been constructed (the “recursive” part).

13 Winter 2006CISC121 - Prof. McLeod13 Recursive Definitions For example, the factorial function, n!, is evaluated as: n! = n(n-1)(n-2)(n-3)…(2)(1) So 15! = 15(14)(13)(12)(11)… = 1307674368000. Or, in terms of a mathematical definition:

14 Winter 2006CISC121 - Prof. McLeod14 Recursive Definitions - Cont. Or, in terms of a recursive definition: The upper part is the anchor, and the lower part is the definition of the rules that are used to get all other values. It is also called the “inductive step”. The lower part is recursive.

15 Winter 2006CISC121 - Prof. McLeod15 Coding a Recursive Definition In code: public int factorial (int n) { if (n == 0) return 1; else return n * factorial(n – 1); } // end factorial method

16 Winter 2006CISC121 - Prof. McLeod16 Coding a Recursive Definition – Cont. “But, wait!” you say! Can’t this just be done in a loop? Yes, most recursive codes can be carried out using loop(s) instead. However, the “looping” version is seldom as compact as the recursive one. Recursion is used in a program when it produces code that is shorter and more easily understood (and debugged!) than code using a loop. Recursive versions are usually slower than looping versions.

17 Winter 2006CISC121 - Prof. McLeod17 Coding a Recursive Definition – Cont. A non-recursive factorial method: public int factorial (int n) { int f = 1; if (n > 0) for (int i = 2; i <= n; i++) f *= i; return f; } // end factorial method

18 Winter 2006CISC121 - Prof. McLeod18 Coding a Recursive Definition – Cont. (Note that we are ignoring the very real possibility of numeric overflow in these factorial methods. It would be better to use a long, or even an “ BigInt ” variable.)

19 Winter 2006CISC121 - Prof. McLeod19 Coding a Recursive Definition – Cont. Back to the recursive factorial method: public int factorial (int n) { if (n == 0) return 1; else return n * factorial(n – 1); } // end factorial method This is a slightly more “elegant” piece of code, and it is easy to write and debug. What is not so easy to understand is how it works!

20 Winter 2006CISC121 - Prof. McLeod20 Back to Stacks - Activation Frames Stacks are an integral part of computer architecture. For example, Java byte code is run by the “Java Virtual Machine”, or “JVM”. The JVM is stack – based. Each thread (or process…) in the JVM has its own private run-time stack in memory (our programs are “single threaded”). Each run-time stack contains “activation frames” – one for each method that has been activated. Only one activation frame (or method) can be active at a time for each thread. An activation frame is created, or “pushed”, every time a method is invoked. When the method is completed, the frame is popped off the stack.

21 Winter 2006CISC121 - Prof. McLeod21 Activation Frames An activation frame (or “stack frame” or “activation record”) contains (among other things): –All local variables and code. –A link to the frame of the calling method, so that control can be returned to line of code in the caller immediately after the method call. –Information for catching exceptions. –An “operand stack”, which is another stack that is used by the JVM as a source of arguments and a repository of results when expressions are evaluated.

22 Winter 2006CISC121 - Prof. McLeod22 Demonstration Run “RunTimeStackDemo.java” in debug mode, stepping though method calls and observe thread stack display.

23 Winter 2006CISC121 - Prof. McLeod23 Recursion and the Run-Time Stack Consider another simple recursive definition (ignore n<0): public static double power (double x, int n) { if (n == 0) return 1.0; else return x * power(x, n-1); } // end power

24 Winter 2006CISC121 - Prof. McLeod24 Recursion and the Run-Time Stack – Cont. In a main method: public static void main(String[] args) { double z = power(5.6, 2); } // end main Look at what happens in debug mode in eclipse…

25 Winter 2006CISC121 - Prof. McLeod25 An activation frame for this first call to power is pushed onto the run-time stack, and execution is transferred to this frame (execution does not continue in main). The power method runs until it hits the second call to power on line: power(5.6, 1) // second call Recursion and the Run-Time Stack – Cont. main power 5.6, 2

26 Winter 2006CISC121 - Prof. McLeod26 Execution in the first call frame stops and a frame for the second call is pushed onto the stack. Execution in the second call frame continues until it hits the third call to power : power(5.6, 0) // third call Recursion and the Run-Time Stack – Cont. main power 5.6, 1 power

27 Winter 2006CISC121 - Prof. McLeod27 Execution in the second call frame stops and a frame for the third call is pushed onto the stack. Now, power executes until it reaches the line: This causes the value 1.0 to be placed at the “Return value” part of the third call’s activation frame. Recursion and the Run-Time Stack – Cont. main power 5.6, 0 power return 1.0;

28 Winter 2006CISC121 - Prof. McLeod28 This third call to power completes, and the third call’s frame is popped off the stack. The second call’s frame accepts the value of 1.0, and execution resumes when 5.6 * 1.0 is calculated. Recursion and the Run-Time Stack – Cont. main power 1.0

29 Winter 2006CISC121 - Prof. McLeod29 This allows the second call’s frame to complete execution. The resulting value (5.6) is placed in the second call’s Return value part of the frame. Recursion and the Run-Time Stack – Cont. main power 5.6

30 Winter 2006CISC121 - Prof. McLeod30 Recursion and the Run-Time Stack – Cont. The second call’s frame is popped off the stack, and the value “5.6” is given to the first call’s frame and execution resumes at line when 5.6 * 5.6 is calculated. The first call’s execution completes and the first call’s frame is popped off the stack providing the value “31.36” to the next frame on the stack. main power 31.36

31 Winter 2006CISC121 - Prof. McLeod31 Recursion and the Run-Time Stack – Cont. Execution resumes in the main frame, where the value “31.36” is put into the variable z. See the factorial method, as well (when does the factorial calculation actually take place?). main y=31.36

32 Winter 2006CISC121 - Prof. McLeod32 Recursion and the Run-Time Stack – Summary Execution stops at any method call and execution is passed to that method. Information on the calling method is preserved in the run- time stack, and a new frame is created for the newly called method. As recursive calls continue, the frames continue to pile up, each one waiting to complete their execution. Finally, the last recursive call is made and the “anchor condition” or the “stopping case” is encountered. The method completes without making another recursive call and may provide a Return value, for example.

33 Winter 2006CISC121 - Prof. McLeod33 Recursion and the Run-Time Stack – Summary, Cont. The frame for the last call, the “stopping case” is popped off the stack, with the Return value being passed down into the next frame. The frame below accepts the Return value, completes, gets popped off, and so on, until the only frame remaining is the frame that contains the original call to the recursive method. This frame accepts the value from the method, and continues its execution.

34 Winter 2006CISC121 - Prof. McLeod34 Another Example Remember that the activation frames can also hold code after the recursive call. See TestRecursion.java


Download ppt "Winter 2006CISC121 - Prof. McLeod1 Stuff No stuff today!"

Similar presentations


Ads by Google