Programming Abstractions

Slides:



Advertisements
Similar presentations
Recursion CS 367 – Introduction to Data Structures.
Advertisements

CS50 SECTION: WEEK 3 Kenny Yu. Announcements  Watch Problem Set 3’s walkthrough online if you are having trouble.  Problem Set 1’s feedback have been.
Search and Recursion pt. 2 CS221 – 2/25/09. How to Implement Binary Search Take a sorted data-set to search and a key to search for Start at the mid-point.
Lesson 19 Recursion CS1 -- John Cole1. Recursion 1. (n) The act of cursing again. 2. see recursion 3. The concept of functions which can call themselves.
Recursion Introduction to Computing Science and Programming I.
Recursion. Objectives At the conclusion of this lesson, students should be able to Explain what recursion is Design and write functions that use recursion.
Recursion. Idea: Some problems can be broken down into smaller versions of the same problem Example: n! 1*2*3*…*(n-1)*n n*factorial of (n-1)
Digression: the “Stack” 1 CS502 Spring 2006 Digression: the “Stack” Imagine the following program:– int factorial(int n){ if (n
CS212: DATASTRUCTURES Lecture 3: Recursion 1. Lecture Contents 2  The Concept of Recursion  Why recursion?  Factorial – A case study  Content of a.
15-1 Chapter-18: Recursive Methods –Introduction to Recursion –Solving Problems with Recursion –Examples of Recursive Methods.
CSE 12 – Basic Data Structures Cynthia Bailey Lee Some slides and figures adapted from Paul Kube’s CSE 12 CS2 in Java Peer Instruction Materials by Cynthia.
CS 106X – Programming Abstractions in C++ Cynthia Bailey Lee CS2 in C++ Peer Instruction Materials by Cynthia Bailey Lee is licensed under a Creative Commons.
Recursion Textbook chapter Recursive Function Call a recursive call is a function call in which the called function is the same as the one making.
Sequential & Object oriented Programming
CS212: DATASTRUCTURES Lecture 3: Recursion 1. Lecture Contents 2  The Concept of Recursion  Why recursion?  Factorial – A case study  Content of a.
COMP Recursion, Searching, and Selection Yi Hong June 12, 2015.
1 7.Algorithm Efficiency What to measure? Space utilization: amount of memory required  Time efficiency: amount of time required to process the data.
CS 106X – Programming Abstractions in C++ Cynthia Bailey Lee CS2 in C++ Peer Instruction Materials by Cynthia Bailey Lee is licensed under a Creative Commons.
1 Chapter 8 Recursion. 2 Objectives  To know what is a recursive function and the benefits of using recursive functions (§8.1).  To determine the base.
Winter 2006CISC121 - Prof. McLeod1 Stuff No stuff today!
1 Recursive algorithms Recursive solution: solve a smaller version of the problem and combine the smaller solutions. Example: to find the largest element.
Searching CSE 103 Lecture 20 Wednesday, October 16, 2002 prepared by Doug Hogan.
CS162 - Topic #10 Lecture: Recursion –The Nature of Recursion –Tracing a Recursive Function –Work through Examples of Recursion Programming Project –Discuss.
Recursion. Objectives At the conclusion of this lesson, students should be able to Explain what recursion is Design and write functions that use recursion.
Function Recursion to understand recursion you must understand recursion.
Recursion – some examples. Sum of Squares Write Vertical.
Programming Abstractions Cynthia Lee CS106X. Recursion! The exclamation point isn’t there only because this is so exciting, it also relates to one of.
Recursion You may have seen mathematical functions defined using recursion Factorial(x) = 1 if x
Recursion Powerful Tool
Recursion.
CMSC201 Computer Science I for Majors Lecture 19 – Recursion
Andy Wang Object Oriented Programming in C++ COP 3330
Chapter 13 Recursion Copyright © 2016 Pearson, Inc. All rights reserved.
Chapter Topics Chapter 16 discusses the following main topics:
Recursion Version 1.0.
to understand recursion you must understand recursion
Programming Abstractions
Programming Abstractions
OBJECT ORIENTED PROGRAMMING II LECTURE 23 GEORGE KOUTSOGIANNAKIS
Week 13: Searching and Sorting
Programming Abstractions
Introduction to Computing Science and Programming I
Programming Abstractions
COMP 53 – Week Seven Big O Sorting.
Fundamentals of structural programming
Andy Wang Object Oriented Programming in C++ COP 3330
Introduction to C++ Recursion
to understand recursion you must understand recursion
Announcements Final Exam on August 17th Wednesday at 16:00.
Recursion "To understand recursion, one must first understand recursion." -Stephen Hawking.
Binary Search Back in the days when phone numbers weren’t stored in cell phones, you might have actually had to look them up in a phonebook. How did you.
Last Class We Covered Data representation Binary numbers ASCII values
Programming Abstractions
Programming Abstractions
Programming Abstractions
Recursion Data Structures.
CMSC201 Computer Science I for Majors Lecture 19 – Recursion
Announcements Final Exam on August 19th Saturday at 16:00.
Programming Abstractions
Programming Abstractions
Module 1-10: Recursion.
Announcements Final Exam on December 25th Monday at 16:00.
Chapter 17 Recursion.
Recursion.
And now for something completely different . . .
Yan Shi CS/SE 2630 Lecture Notes
Chapter 18 Recursion.
Dr. Sampath Jayarathna Cal Poly Pomona
Self-Referencing Functions
Chapter 13 Recursion Copyright © 2010 Pearson Addison-Wesley. All rights reserved.
Presentation transcript:

Programming Abstractions CS106B Cynthia Lee

Recursion! The exclamation point isn’t there only because this is so exciting, it also relates to one of our recursion examples….

Recursion

Factorial! Recursive mathematical definition n! = Recursive code if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! (0!=1 but for simplicity we’ll just consider the domain n>0 for today) Recursive code

Designing a recursive algorithm Recursion is a way of taking a big problem and repeatedly breaking it into smaller and smaller pieces until it is so small that it can be so easily solved that it almost doesn't even need solving. There are two parts of a recursive algorithm: base case: where we identify that the problem is so small that we trivially solve it and return that result recursive case: where we see that the problem is still a bit too big for our taste, so we chop it into smaller bits and call our self (the function we are in now) on the smaller bits to find out the answer to the problem we face

Factorial! Recursive definition n! = Recursive code if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! Recursive code long factorial ( int n ) { if (n==1) return 1; else return n*factorial(n-1); }

Factorial! Recursive definition n! = if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! Recursive code: imagining more concrete examaples long factorialOf6 () { return 6 * factorialOf5(); } long factorialOf5() { return 120;

Factorial! Recursive definition n! = if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! Recursive code: imagining more concrete examaples long factorial ( int n ) { if (n==1) return 1; else { int nminus1fact = pretendIJustMagicallyKnowFactorialOfThis(n-1); return n*nminus1fact; }

Factorial! Recursive definition n! = Recursive code if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! Recursive code long factorial ( int n ) { if (n==1) return 1; else { int nminus1fact = factorial(n-1); return n*nminus1fact; }

Factorial! Recursive definition n! = Recursive code if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! Recursive code long factorial ( int n ) { if (n==1) return 1; else return n*factorial(n-1); }

Factorial! Recursive code Recursive definition n! = if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! long factorial ( int n ) { if (n==1) return 1; else return n*factorial(n–1); } Pro tip: the recursive “leap of faith” This concept has become part of the mythology of Stanford’s CS106B/X classes. It speaks to the idea that recursion will start to make sense to you when you just trust that the recursive part works. One way of tricking your brain into summoning this trust is imagining that the recursive call instead calls some different (non-recursive) function that calculates the same thing, like we did at first for factorial().

Digging deeper in the recursion I know I just told you about the recursive leap of faith and that, for algorithm design purposes, you should mentally flatten the recursion. But before we put that tip into practice, it helps to orient ourselves to the full complexity.

Factorial! Recursive code Recursive definition n! = if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! long factorial ( int n ) { cout << n << endl; //added code if (n==1) return 1; else return n*factorial(n–1); } What is the third thing printed when we call factorial(10)? 2 3 7 8 Other/none/more

How does this look in memory? Stack Heap

How does this look in memory? Recursive code main() long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 10; long xfac = 0; xfac = factorial(x); myfunction() x: xfac: 10 factorial() n: 10 Heap

Memory (A) Memory (B) Memory (C) main() main() main() myfunction() x: xfac: 10 myfunction() x: xfac: 10 myfunction() x: xfac: 10 factorial() n: 10 factorial() n: 9 factorial() n: 10 9 factorial() n: 9 Heap Heap Heap (D) Other/none of the above

The “stack” part of memory is a stack Function call = push Return = pop

The “stack” part of memory is a stack Recursive code main() long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; //smaller test case long xfac = 0; xfac = factorial(x); myfunction() x: xfac: 4 factorial() n: 4 Heap

The “stack” part of memory is a stack Recursive code main() long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); myfunction() x: xfac: 4 factorial() n: 4 factorial() n: 3 Heap

The “stack” part of memory is a stack Recursive code main() long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); myfunction() x: xfac: 4 factorial() n: 4 factorial() n: 3 factorial() n: 2 Heap

The “stack” part of memory is a stack Recursive code main() long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); myfunction() x: xfac: 4 factorial() n: 4 factorial() n: 3 factorial() n: 2 factorial() n: 1 Heap

Factorial! Recursive code Recursive definition n! = if n is 1, then n! = 1 if n > 1, then n! = n * (n – 1)! long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } What is the fourth value ever returned when we call factorial(10)? 4 6 10 24 Other/none/more than one

The “stack” part of memory is a stack main() Recursive code myfunction() x: xfac: 4 long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); factorial() n: 4 factorial() n: 3 factorial() n: 2 factorial() n: 1 Return 1 Heap

The “stack” part of memory is a stack main() Recursive code myfunction() x: xfac: 4 long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); factorial() n: 4 factorial() n: 3 factorial() n: 2 Return 2 Heap

The “stack” part of memory is a stack main() Recursive code myfunction() x: xfac: 4 long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); factorial() n: 4 factorial() n: 3 Return 6 Heap

The “stack” part of memory is a stack main() Recursive code myfunction() x: xfac: 4 long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } void myfunction(){ int x = 4; long xfac = 0; xfac = factorial(x); factorial() n: 4 Return 24 Heap

Factorial! Iterative version Recursive version long factorial(int n) { long f = 1; while ( n > 1 ) { f = f * n; n = n – 1; } return f; long factorial ( int n ) { cout << n << endl; if (n==1) return 1; else return n*factorial(n–1); } NOTE: sometimes iterative can be much faster because it doesn’t have to push and pop stack frames. Function calls have overhead in terms of space and time to set up and tear down.

Announcement: Recursive art contest! Go to http://recursivedrawing.com/ Make recursive art Win prizes! Come to my office hours and see my Wall of Fame of past recursive art submissions! Submission deadline: Wednesday of Week 4 (October 14) Submission procedure: Email me: cbl@stanford.edu

Wall of Fame

Classic CS problem: searching

Imagine storing sorted data in an array How long does it take us to find a number we are looking for? 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95

Imagine storing sorted data in an array How long does it take us to find a number we are looking for? If you start at the front and proceed forward, each item you examine rules out 1 item 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95

Imagine storing sorted data in an array 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95 If instead we jump right to the middle, one of three things can happen: The middle one happens to be the number we were looking for, yay! We realize we went too far We realize we didn’t go far enough

Imagine storing sorted data in an array 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95 If instead we jump right to the middle, one of three things can happen: The middle one happens to be the number we were looking for, yay! We realize we went too far We realize we didn’t go far enough Ruling out HALF the options in one step is so much faster than only ruling out one!

Binary search 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95 Let’s say the answer was 3, “we didn’t go far enough” We ruled out the entire first half, and now only have the second half to search We could start at the front of the second half and proceed forward…

Binary search 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95 Let’s say the answer was 3, “we didn’t go far enough” We ruled out the entire first half, and now only have the second half to search We could start at the front of the second half and proceed forward…but why do that when we know we have a better way? Jump right to the middle of the region to search

Binary search 1 2 3 4 5 6 7 8 9 10 13 25 29 33 51 89 90 95 Let’s say the answer was 3, “we didn’t go far enough” We ruled out the entire first half, and now only have the second half to search We could start at the front of the second half and proceed forward…but why do that when we know we have a better way? Jump right to the middle of the region to search RECURSION!!

Designing a recursive algorithm Recursion is a way of taking a big problem and repeatedly breaking it into smaller and smaller pieces until it is so small that it can be so easily solved that it almost doesn't even need solving. There are two parts of a recursive algorithm: base case: where we identify that the problem is so small that we trivially solve it and return that result recursive case: where we see that the problem is still a bit too big for our taste, so we chop it into smaller bits and call our self (the function we are in now) on the smaller bits to find out the answer to the problem we face

To write a recursive function, we need base case(s) and recursive call(s) What would be a good base case for our Binary Search function? Only three items remain: save yourself an unnecessary function call that would trivially divide them into halves of size 1, and just check all three. Only two items remain: can’t divide into two halves with a middle, so just check the two. Only one item remains: just check it. No items remain: obviously we didn’t find it. More than one

Binary Search bool binarySearch(Vector<int>& data, int key){ return binarySearch(data, key, 0, data.size()-1); } bool binarySearch(Vector<int>& data, int key, int start, int end){ //to be continued…