Introduction to Recursion and Recursive Algorithms

Slides:



Advertisements
Similar presentations
Basics of Recursion Programming with Recursion
Advertisements

Chapter 20 Recursion.
Dynamic Programming Introduction Prof. Muhammad Saeed.
Lecture 22, Revision 1 Lecture notes Java code – CodeFromLectures folder* Example class sheets – 4 of these plus solutions Extra examples (quicksort) Lab.
Formal Models of Computation Part II The Logic Model
Towers of Hanoi Move n (4) disks from pole A to pole C such that a disk is never put on a smaller disk A BC ABC.
Computer Science Recursion Yuting Zhang Allegheny College, 04/24/06.
Lilian Blot Recursion Autumn 2012 TPOP 1. Lilian Blot Recursion Autumn 2012 TPOP 2.
© 2010 Pearson Addison-Wesley. All rights reserved. Addison Wesley is an imprint of CHAPTER 7: Recursion Java Software Structures: Designing and Using.
Starting Out with Java: From Control Structures through Objects
Copyright © 2009 Pearson Education, Inc. Publishing as Pearson Addison-Wesley Java Software Solutions Foundations of Program Design Sixth Edition by Lewis.
Factorial Recursion stack Binary Search Towers of Hanoi
Recursion.
Fall 2008Programming Development Techniques 1 Topic 3 Linear Recursion and Iteration September 2008.
Recursion. Binary search example postponed to end of lecture.
Scott Grissom, copyright 2004 Chapter 5 Slide 1 Analysis of Algorithms (Ch 5) Chapter 5 focuses on: algorithm analysis searching algorithms sorting algorithms.
Programming with Recursion
Chapter 10 Recursion. Copyright © 2005 Pearson Addison-Wesley. All rights reserved Chapter Objectives Explain the underlying concepts of recursion.
16/23/2015 9:48 AM6/23/2015 9:48 AM6/23/2015 9:48 AMRecursion Recursion Recursion is when a function calls itself to implement an algorithm. Really a paradigm.
Recursive Algorithms Nelson Padua-Perez Chau-Wen Tseng Department of Computer Science University of Maryland, College Park.
Recursion.
Recursion Chapter 7. Chapter 7: Recursion2 Chapter Objectives To understand how to think recursively To learn how to trace a recursive method To learn.
CHAPTER 10 Recursion. 2 Recursive Thinking Recursion is a programming technique in which a method can call itself to solve a problem A recursive definition.
A Review of Recursion Dr. Jicheng Fu Department of Computer Science University of Central Oklahoma.
Recursion. Basic problem solving technique is to divide a problem into smaller subproblems These subproblems may also be divided into smaller subproblems.
Stacks & Recursion. Stack pushpop LIFO list - only top element is visible top.
A Computer Science Tapestry 1 Recursion (Tapestry 10.1, 10.3) l Recursion is an indispensable technique in a programming language ä Allows many complex.
Chapter 13 Recursion. Topics Simple Recursion Recursion with a Return Value Recursion with Two Base Cases Binary Search Revisited Animation Using Recursion.
1 Decrease-and-Conquer Approach Lecture 06 ITS033 – Programming & Algorithms Asst. Prof. Dr. Bunyarit Uyyanonvara IT Program, Image and Vision Computing.
Recursion Chapter 7. Chapter Objectives  To understand how to think recursively  To learn how to trace a recursive method  To learn how to write recursive.
Week 5 - Monday.  What did we talk about last time?  Linked list implementations  Stacks  Queues.
Chapter 12 Recursion, Complexity, and Searching and Sorting
Recursion Chapter 11. The Basics of Recursion: Outline Introduction to Recursion How Recursion Works Recursion versus Iteration Recursive Methods That.
Lecturer: Dr. AJ Bieszczad Chapter 11 COMP 150: Introduction to Object-Oriented Programming 11-1 l Basics of Recursion l Programming with Recursion Recursion.
Recursion and Dynamic Programming. Recursive thinking… Recursion is a method where the solution to a problem depends on solutions to smaller instances.
Stephen P. Carl - CS 2421 Recursion Reading : Chapter 4.
Slides prepared by Rose Williams, Binghamton University ICS201 Lecture 19 : Recursion King Fahd University of Petroleum & Minerals College of Computer.
RecursionRecursion Recursion You should be able to identify the base case(s) and the general case in a recursive definition To be able to write a recursive.
224 3/30/98 CSE 143 Recursion [Sections 6.1, ]
Computer Science Department Data Structure & Algorithms Lecture 8 Recursion.
Reading – Chapter 10. Recursion The process of solving a problem by reducing it to smaller versions of itself Example: Sierpinski’s TriangleSierpinski’s.
Review Introduction to Searching External and Internal Searching Types of Searching Linear or sequential search Binary Search Algorithms for Linear Search.
Chapter 8 Recursion Modified.
Recursion. What is recursion? Rules of recursion Mathematical induction The Fibonacci sequence Summary Outline.
CSC 221: Recursion. Recursion: Definition Function that solves a problem by relying on itself to compute the correct solution for a smaller version of.
Data Structures R e c u r s i o n. Recursive Thinking Recursion is a problem-solving approach that can be used to generate simple solutions to certain.
Java Programming: Guided Learning with Early Objects Chapter 11 Recursion.
IB Computer Science Unit 5 – Advanced Topics Recursion.
By: Lokman Chan Recursive Algorithm Recursion Definition: A function that is define in terms of itself. Goal: Reduce the solution to.
Chapter 11Java: an Introduction to Computer Science & Programming - Walter Savitch 1 Chapter 11 l Basics of Recursion l Programming with Recursion Recursion.
© 2011 Pearson Education, publishing as Addison-Wesley Chapter 8: Recursion Presentation slides for Java Software Solutions for AP* Computer Science 3rd.
© Janice Regan, CMPT 128, February CMPT 128: Introduction to Computing Science for Engineering Students Recursion.
Recursion A recursive definition is one which uses the word or concept being defined in the definition itself Example: “A computer is a machine.
Recursion ITI 1121 N. El Kadri. Reminders about recursion In your 1 st CS course (or its equivalent), you have seen how to use recursion to solve numerical.
Recursion in Java The answer to life’s greatest mysteries are on the last slide.
CS 116 Object Oriented Programming II Lecture 13 Acknowledgement: Contains materials provided by George Koutsogiannakis and Matt Bauer.
CSE 143 Lecture 9: introduction to recursion reading: 12.1.
CSC 143 P 1 CSC 143 Recursion [Chapter 5]. CSC 143 P 2 Recursion  A recursive definition is one which is defined in terms of itself  Example:  Compound.
Welcome to Recursion! Say what?!? Recursion is… the process of solving large problems by simplifying them into smaller ones. similar to processing using.
Recursion.
Recursion DRILL: Please take out your notes on Recursion
Java 4/4/2017 Recursion.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Announcements Final Exam on August 17th Wednesday at 16:00.
Recursive Thinking Chapter 9 introduces the technique of recursive programming. As you have seen, recursive programming involves spotting smaller occurrences.
Recursion "To understand recursion, one must first understand recursion." -Stephen Hawking.
Applied Algorithms (Lecture 17) Recursion Fall-23
Stacks & Recursion.
Recursion Taken from notes by Dr. Neil Moore
Yan Shi CS/SE 2630 Lecture Notes
Presentation transcript:

Introduction to Recursion and Recursive Algorithms CS2110

Different Views of Recursion Recursive Definition: n! = n * (n-1)! (non-math examples are common too) Recursive Procedure: a procedure that calls itself. Recursive Data Structure: a data structure that contains a pointer to an instance of itself: public class ListNode { Object nodeItem; ListNode next, previous; … }

Recursion in Algorithms Recursion is a technique that is useful for defining relationships, and for designing algorithms that implement those relationships. Recursion is a natural way to express many algorithms. For recursive data-structures, recursive algorithms are a natural choice

What Is Recursion? A Definition Is Recursive If It Is Defined In Terms Of Itself We use them in grammar school e.g. what is a noun phrase? a noun an adjective followed by a noun phrase Descendants the person’s children all the children’s descendants

What Is Recursion? Think self-referential definition A definition is recursive if it is defined in terms of itself Exponentiation - x raised to the y power if y is 0, then 1 otherwise it’s x * (x raised to the y-1 power)

Other recursive definitions in mathematics Factorial: n! = n (n-1)! and 0! = 1! = 1 Fibonacci numbers: F(0) = F(1) = 1 F(n) = F(n-1) + F(n-2) for n > 1 Note base case Definition can’t be completely self-referential Must eventually come down to something that’s solved “directly”

I know the steps needed to write a simple recursive method in Java Strongly Agree Agree Disagree Strongly Disagree

Recursive Factorial public static int factorial (int n) { if (n == 1) return 1; else return n * factorial(n-1); } Exercise: trace execution (show method calls) for n=5

Why Do Recursive Methods Work? Activation Records on the Run-time Stack are the key: Each time you call a function (any function) you get a new activation record. Each activation record contains a copy of all local variables and parameters for that invocation. The activation record remains on the stack until the function returns, then it is destroyed. Try yourself: use your IDE’s debugger and put a breakpoint in the recursive algorithm Look at the call-stack.

Broken Recursive Factorial public static int Brokenfactorial(int n){ int x = Brokenfactorial(n-1); if (n == 1) return 1; else return n * x; } What’s wrong here? Trace calls “by hand” BrFact(2) -> BrFact(1) -> BrFact(0) -> BrFact(-1) -> BrFact(-2) -> … Problem: we do the recursive call first before checking for the base case Never stops! Like an infinite loop!

Recursive Design Recursive methods/functions require: 1) One or more (non-recursive) base cases that will cause the recursion to end. if (n == 1) return 1; 2) One or more recursive cases that operate on smaller problems and get you closer to the base case. return n * factorial(n-1); Note: The base case(s) should always be checked before the recursive call.

Rules for Recursive Algorithms Base case - must have a way to end the recursion Recursive call - must change at least one of the parameters and make progress towards the base case exponentiation (x,y) base: if y is 0 then return 1 recursive: else return (multiply x times exponentiation(x,y-1))

How to Think/Design with Recursion Many people have a hard time writing recursive algorithms The key: focus only at the current “stage” of the recursion Handle the base case, then… Decide what recursive-calls need to be made Assume they work (as if by magic) Determine how to use these calls’ results

Example: List Processing Is an item in a list? First, get a reference current to the first node (Base case) If current is null, return false (Base case #2) If the first item equals the target, return true (Recursive case – might be on the remainder of the list) current = current.next return result of recursive call on new current

Next: Trees and Grammars Lab on binary tree data structures Maybe: HW5 on grammars Lecture Later: Recursion vs. iteration Which to choose? Does it matter? Maybe Later: recursion as an design strategy

Next: Time Complexity and Recursion Recursion vs. iteration Which to choose? Does it matter? Later: recursion as an design strategy

Recursion vs. Iteration Interesting fact: Any recursive algorithm can be re-written as an iterative algorithm (loops) Not all programming languages support recursion: COBOL, early FORTRAN. Some programming languages rely on recursion heavily: LISP, Prolog, Scheme.

To Recurse or Not To Recurse? Recursive solutions often seem elegant Sometimes recursion is an efficient design strategy But sometimes it’s definitely not Important! we can define recursively and implement non-recursively Many recursive algorithms can be re-written non-recursively Use an explicit stack Remove tail-recursion (compilers often do this for you)

To Recurse or Not to Recurse? Sorting Selection sort vs. mergesort – which to choose? Factorial Could just write a loop. Any advantage to the recursive version? Binary search We’ll see two versions. Which to choose? Fibonacci Let’s consider Fibonacci carefully…

Recursive Fibonacci method This is elegant code, no? long fib(int n) { if ( n == 0 ) return 1; if ( n == 1 ) return 1; return fib(n-1) + fib(n-2); } Let’s start to trace it for fib(6)

Trace of fib(5) For fib(5), we call fib(4) and fib(3) For fib(2), we call fib(1) and fib(0). Base cases! fib(1). Base case!

Fibonacci: recursion is a bad choice Note that subproblems (like fib(2) ) repeat, and solved again and again We don’t remember that we’ve solved one of our subproblems before For this problem, better to store partial solutions instead of recalculating values repeatedly Turns out to have exponential time-complexity!

Non-recursive Fibonacci Two bottom-up iterative solutions: Create an array of size n, and fill with values starting from 1 and going up to n Or, have a loop from small values going up, but only remember two previous Fibonacci values use them to compute the next one (See next slide)

Iterative Fibonacci long fib(int n) { if ( n < 2 ) return 1; long answer; long prevFib=1, prev2Fib=1; // fib(0) & fib(1) for (int k = 2; k <= n; ++k) { answer = prevFib + prev2Fib; prev2Fib = prevFib; prevFib = answer; } return answer;

Next: Putting Recursion to Work Divide and Conquer design strategy Its form Examples: Binary Search Merge Sort Time complexity issues

Divide and Conquer It is often easier to solve several small instances of a problem than one large one. divide the problem into smaller instances of the same problem solve (conquer) the smaller instances recursively combine the solutions to obtain the solution for original input Must be able to solve one or more small inputs directly This is an algorithm design strategy Computer scientists learn many more of these

General Strategy for Div. & Conq. Solve (an input I) n = size(I) if (n <= smallsize) solution = directlySolve(I); else divide I into I1, …, Ik. for each i in {1, …, k} Si = solve(Ii); solution = combine(S1, …, Sk); return solution;

Why Divide and Conquer? Sometimes it’s the simplest approach Divide and Conquer is often more efficient than “obvious” approaches E.g. BinarySearch vs. Sequential Search E.g. Mergesort, Quicksort vs. SelectionSort But, not necessarily efficient Might be the same or worse than another approach We must analyze each algorithm's time complexity Note: divide and conquer may or may not be implemented recursively

Top-Down Strategy Divide and Conquer algorithms illustrate a top-down strategy Given a large problem, identify and break into smaller subproblems Solve those, and combine results Most recursive algorithms work this way The alternative? Bottom-up Identify and solve smallest subproblems first Combine to get larger solutions until solve entire problem

Binary Search of a Sorted Array first mid last Strategy Find the midpoint of the array Is target equal to the item at midpoint? If smaller, look in the first half If larger, look in second half

Binary Search (non-recursive) int binSearch ( array[], target) { int first = 0; int last = array.length-1; while ( first <= last ) { mid = (first + last) / 2; if ( target == array[mid] ) return mid; // found it else if ( target < array[mid] ) // must be in 1st half last = mid -1; else // must be in 2nd half first = mid + 1 } return -1; // only got here if not found above

Binary Search (recursive) int binSearch ( array[], first, last, target) { if ( first <= last ) { mid = (first + last) / 2; if ( target == array[mid] ) // found it! return mid; else if ( target < array[mid] ) // must be in 1st half return binSearch( array, first, mid-1, target); else // must be in 2nd half return binSearch(array, mid+1, last, target); } return -1; No loop! Recursive calls takes its place But don’t think about that if it confuses you! Base cases checked first? (Why? Zero items? One item?)

Mergesort is Classic Divide & Conquer

Algorithm: Mergesort Specification: Algorithm: Input: Array E and indexes first, and Last, such that the elements E[i] are defined for first <= i <= last. Output: E[first], …, E[last] is sorted rearrangement of the same elements Algorithm: void mergeSort(Element[] E, int first, int last){ if (first < last) { int mid = (first+last)/2; mergeSort(E, first, mid); mergeSort(E, mid+1, last); merge(E, first, mid, last); // merge 2 sorted halves }

Exercise: Trace Mergesort Execution Can you trace MergeSort() on this list? A = {8, 3, 2, 9, 7, 1, 5, 4};

Efficiency of Mergesort Wait for CS2150 and CS4102 to study efficiency of this and other recursive algorithms But… It is more efficient that other sorts like Selection Sort, Bubble Sort, Insertion Sort It’s O(n lg n) which is the same order-class as the most efficient sorts (also quicksort and heapsort) The point is that the D&C approach matters here, and a recursive definition and implementation is a “win”

Merging Sorted Sequences Problem: Given two sequences A and B sorted in non-decreasing order, merge them to create one sorted sequence C Input size: C has n items, and A and B have n/2 Strategy: Determine the first item in C: it should be the smaller of the first item in A and the first in B. Suppose it is the first item of A. Copy that to C. Then continue merging B with “rest of A” (without the item copied to C). Repeat!

Algorithm: Merge merge(A, B, C) if (A is empty) else if (B is empty) append what’s left in B to C else if (B is empty) append what’s left in A to C else if (first item in A <= first item in B) append first item in A to C merge (rest of A, B, C) else // first item in B is smaller append first item in B to C merge (A, rest of B, C) return

Summary of Recursion Concepts Recursion is a natural way to solve many problems Sometimes it’s a clever way to solve a problem that is not clearly recursive Sometimes recursion produces an efficient solution (e.g. mergesort) Sometimes it doesn’t (e.g. fibonacci) To use recursion or not is a design decision for your “toolbox”

Recursion: Design and Implementation “The Rules” Identify one or more base (simple) cases that can be solved without recursion In your code, handle these first!!! Determine what recursive call(s) are needed for which subproblems Also, how to use results to solve the larger problem Hint: At this step, don’t think about how recursive calls process smaller inputs! Just assume they work!

Exercise: Find Max and Min Given a list of elements, find both the maximum element and the minimum element Obvious solution: Consider first element to be max Consider first element to be min Scan linearly from 2nd to last, and update if something larger then max or if something smaller than min Class exercise: Write a recursive function that solves this using divide and conquer. Prototype: void maxmin (list, first, last, max, min); Base case(s)? Subproblems? How to combine results?

What’s Next? Recursive Data Structures Binary trees Representation Recursive algorithms Binary Search Trees Binary Trees with constraints Parallel Programming using Threads