Recursive problem-solving approaches have a number of elements in common. When a recursive method is called to solve a problem, the method actually is capable of solving only the simplest case(s), or base case(s). If the method is called with a base case, the method returns a result. If the method is called with a more complex problem, the method typically divides the problem into two conceptual piecesa piece that the method knows how to do and a piece that the method does not know how to do. To make recursion feasible, the latter piece must resemble the original problem, but be a slightly simpler or smaller version of it. Because this new problem looks like the original problem, so the method calls a fresh copy of itself to work on the smaller problemthis is referred to as a recursive call and is also called the recursion step. The recursion step normally includes a return statement, because its result will be combined with the portion of the problem the method knew how to solve to form a result that will be passed back to the original caller. This concept of separating the problem into two smaller portions is a form of the divide-and-conquer approach introduced at the beginning of Chapter 6.
The recursion step executes while the original call to the method is still active (i.e., while it has not finished executing). The recursion step can result in many more recursive calls as the method divides each new subproblem into two conceptual pieces. For the recursion to eventually terminate, each time the method calls itself with a simpler version of the original problem, the sequence of smaller and smaller problems must converge on a base case. At that point, the method recognizes the base case and returns a result to the previous copy of the method. A sequence of returns ensues until the original method call returns the final result to the caller.
A recursive method may call another method, which may in turn make a call back to the recursive method. Such a process is known as an indirect recursive call or indirect recursion. For example, method A calls method B, which makes a call back to method A. This is still considered recursion, because the second call to method A is made while the first call to method A is activethat is, the first call to method A has not yet finished executing (because it is waiting on method B to return a result to i) and has not returned to method A's original caller.
To better understand the concept of recursion, let us look at an example of recursion that is quite common to computer usersthe recursive definition of a directory on a computer. A computer normally stores related files in a directory. A directory can be empty, can contain files and/or can contain other directories (usually referred to as subdirectories). Each of these subdirectories, in turn, may also contain both files and directories. If we wanted to list each file in a directory (including all the files in the directory's subdirectories), we would need to create a method that first lists the initial directory's files, then makes recursive calls to list the files in each of that directory's subdirectories. The base case would occur when a directory is reached that does not contain any subdirectories. At this point, all the files in the original directory have been listed and no further recursive calls need to be made.
Introduction to Computers, the Internet and the World Wide Web
Introduction to Java Applications
Introduction to Classes and Objects
Control Statements: Part I
Control Statements: Part 2
Methods: A Deeper Look
Arrays
Classes and Objects: A Deeper Look
Object-Oriented Programming: Inheritance
Object-Oriented Programming: Polymorphism
GUI Components: Part 1
Graphics and Java 2D™
Exception Handling
Files and Streams
Recursion
Searching and Sorting
Data Structures
Generics
Collections
Introduction to Java Applets
Multimedia: Applets and Applications
GUI Components: Part 2
Multithreading
Networking
Accessing Databases with JDBC
Servlets
JavaServer Pages (JSP)
Formatted Output
Strings, Characters and Regular Expressions
Appendix A. Operator Precedence Chart
Appendix B. ASCII Character Set
Appendix C. Keywords and Reserved Words
Appendix D. Primitive Types
Appendix E. (On CD) Number Systems
Appendix F. (On CD) Unicode®
Appendix G. Using the Java API Documentation
Appendix H. (On CD) Creating Documentation with javadoc
Appendix I. (On CD) Bit Manipulation
Appendix J. (On CD) ATM Case Study Code
Appendix K. (On CD) Labeled break and continue Statements
Appendix L. (On CD) UML 2: Additional Diagram Types
Appendix M. (On CD) Design Patterns
Appendix N. Using the Debugger
Inside Back Cover