Towers of Hanoi

In the preceding sections of this chapter, we studied methods that can be easily implemented both recursively and iteratively. In this section, we present a problem whose recursive solution demonstrates the elegance of recursion, and whose iterative solution may not be as apparent.

The Towers of Hanoi is one of the most famous classic problems every budding computer scientist must grapple with. Legend has it that in a temple in the Far East, priests are attempting to move a stack of golden disks from one diamond peg to another (Fig. 15.14). The initial stack has 64 disks threaded onto one peg and arranged from bottom to top by decreasing size. The priests are attempting to move the stack from one peg to another under the constraints that exactly one disk is moved at a time and at no time may a larger disk be placed above a smaller disk. Three pegs are provided, one being used for temporarily holding disks. Supposedly, the world will end when the priests complete their task, so there is little incentive for us to facilitate their efforts.

Figure 15.14. Towers of Hanoi for the case with four disks.

Let us assume that the priests are attempting to move the disks from peg 1 to peg 3. We wish to develop an algorithm that prints the precise sequence of peg-to-peg disk transfers.

If we were to approach this problem with conventional methods, we would rapidly find ourselves hopelessly knotted up in managing the disks. Instead, attacking this problem with recursion in mind allows the steps to be simple. Moving n disks can be viewed in terms of moving only n - 1 disks (hence the recursion) as follows:

  1. Move n - 1 disks from peg 1 to peg 2, using peg 3 as a temporary holding area.
  2. Move the last disk (the largest) from peg 1 to peg 3.
  3. Move the n - 1 disks from peg 2 to peg 3, using peg 1 as a temporary holding area.

The process ends when the last task involves moving n = 1 disk (i.e., the base case). This task is accomplished by simply moving the disk, without the need for a temporary holding area.

Figure 15.15 displays the precise instructions it will take to move the disks from the starting peg to the destination peg. In the constructor (lines 912), the number of disks to be moved (numDisks) is initialized. Method solveTowers (lines 1534) solves the Towers of Hanoi puzzle given the total number of disks (in this case 3 ), the starting peg, the ending peg, and the temporary holding peg as parameters. The base case (lines 1923) occurs when only one disk needs to be moved from the starting peg to the ending peg. In the recursion step (lines 2733), line 27 moves disks - 1 disks from the first peg (sourcePeg) to the temporary holding peg (tempPeg). When all but one of the disks have been moved to the temporary peg, line 30 records the step to move one disk, the largest one, from the start peg to the destination peg. Line 33 finishes the rest of the moves by calling the method solveTowers to recursively move disks - 1 disks from the temporary peg (tempPeg) back to the destination peg (destinationPeg), this time using the first peg (sourcePeg) as the temporary peg.

Figure 15.15. Towers of Hanoi solution with a recursive method.

 1 // Fig. 15.15: TowersOfHanoi.java
 2 // Program solves the towers of Hanoi problem, and
 3 // demonstrates recursion.
 4
 5 public class TowersOfHanoi
 6 {
 7 int numDisks; // number of disks to move
 8
 9 public TowersOfHanoi( int disks )
10 {
11 numDisks = disks;
12 } // end TowersOfHanoi constructor
13
14 // recusively move disks through towers 
15 public void solveTowers( int disks, int sourcePeg, int destinationPeg,
16  int tempPeg ) 
17 { 
18  // base case -- only one disk to move 
19  if ( disks == 1 ) 
20  { 
21  System.out.printf( "
%d --> %d", sourcePeg, destinationPeg ); 
22  return; 
23  } // end if 
24 
25  // recursion step -- move disk to tempPeg, then to destinationPeg 
26  // move ( disks - 1 ) disks from sourcePeg to tempPeg recursively 
27  solveTowers( disks - 1, sourcePeg, tempPeg, destinationPeg ); 
28 
29  // move last disk from sourcePeg to destinationPeg 
30  System.out.printf( "
%d --> %d", sourcePeg, destinationPeg ); 
31 
32  // move ( disks - 1 ) disks from tempPeg to destinationPeg 
33  solveTowers( disks - 1, tempPeg, destinationPeg, sourcePeg ); 
34 } // end method solveTowers 
35 } // end class TowersOfHanoi

Figure 15.16 tests our Towers of Hanoi solution. In the main method (lines 616), line 12 creates a TowersOfHanoi object, passing as a parameter the total number of disks to be moved from one peg to another. Line 15 calls the recursive solveTowers method which outputs the steps to the command prompt.

Figure 15.16. Testing the Towers of Hanoi solution.

 1 // Fig. 15.16: TowersOfHanoiTest.java
 2 // Test the solution to the Towers of Hanoi problem.
 3
 4 public class TowersOfHanoiTest
 5 {
 6 public static void main( String args[] )
 7 {
 8 int startPeg = 1; // value 1 used to indicate startPeg in output
 9 int endPeg = 3; // value 3 used to indicate endPeg in output
10 int tempPeg = 2; // value 2 used to indicate tempPeg in output
11 int totalDisks = 3; // number of disks
12 TowersOfHanoi towersOfHanoi = new TowersOfHanoi( totalDisks );
13
14 // initial nonrecursive call: move all disks.
15 towersOfHanoi.solveTowers( totalDisks, startPeg, endPeg, tempPeg );
16 } // end main
17 } // end class TowersOfHanoiTest
 
1 --> 3
1 --> 2
3 --> 2
1 --> 3
2 --> 1
2 --> 3
1 --> 3
 

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



Java(c) How to Program
Java How to Program (6th Edition) (How to Program (Deitel))
ISBN: 0131483986
EAN: 2147483647
Year: 2003
Pages: 615

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net