The Tower of Hanoi
In the Tower of Hanoi puzzle:
- There are three stacks (towers), numbered 0, 1, 2.
- There are N disks numbered 0, ..., N-1.
=> 0 is the smallest. - Initially, the disks are placed in tower 0, in the order largest to smallest.
=> Smallest on top. - Goal: to move the disks to tower 1 using only legal moves.
- What's a legal move?
- You can move only a disk at the top of a tower.
- You can move only one disk at a time.
- You cannot place a disk on top of a smaller one.
- There are three key steps in the recursion:
- Step 1: move disks 0, ..., N-2 from tower 0 to tower 2
=> Sub problem of smaller size. - Step 2: move disk N-1 from tower 0 to tower 1.
- Step 3: move disks 0, ..., N-2 from tower 2 to tower 1.
=> Sub problem of smaller size.
- Step 1: move disks 0, ..., N-2 from tower 0 to tower 2
- In pseudocode (without base case):
Algorithm towerOfHanoi (n, i, j) Input: Disks numbered 0, ..., n are to be moved from tower i to tower j 1. // ... base case ... // First find the third tower, other than i and j: 2. k = otherTower (i, j) // Step 1: move disks 0,..,n-1 from i to k 3. towerOfHanoi (n-1, i, k) // Step 2: move disk# n from i to j 4. move (n, i, j) // Step 3: move disks 0,...,n-1 from k to j 5. towerOfHanoi (n-1, k, j)
- The base case: move a single disk
Here's the program: (source file)
public class TowerOfHanoi { public static void main(String[] argv) { // A 3-disk puzzle: System.out.println("3-Disk solution: "); solveHanoi(2, 0, 1); // A 4-disk puzzle: System.out.println("4-Disk solution: "); solveHanoi(3, 0, 1); } static void solveHanoi(int n, int i, int j) { // Bottom-out. if (n == 0) { // The smallest disk. move(0, i, j); return; } int k = other(i, j); solveHanoi(n - 1, i, k); // Step 1. move(n, i, j); // Step 2. solveHanoi(n - 1, k, j); // Step 3. } static void move(int n, int i, int j) { // For now, we'll merely print out the move. System.out.println("=> Move disk# " + n + " from tower " + i + " to tower " + j); } static int other(int i, int j) { // return 3-i-j; // this is simpler. // Given two towers, return the third. if ((i == 0) && (j == 1)) { return 2; } else if ((i == 1) && (j == 0)) { return 2; } else if ((i == 1) && (j == 2)) { return 0; } else if ((i == 2) && (j == 1)) { return 0; } else if ((i == 0) && (j == 2)) { return 1; } else if ((i == 2) && (j == 0)) { return 1; } // We shouldn't reach here. return -1; } }
Note:
- The above program merely prints out the moves needed
=> We don't actually maintain the state of each tower.
Next, suppose we want to maintain the state of each tower:
- The ideal data structure is a stack.
- We'll use one stack for each tower.
Here's the program: (source file)
import java.util.*; public class TowerOfHanoi2 { // towers[0], towers[1] and towers[2] are the three stacks. static Stack<Integer>[] towers; public static void main(String[] argv) { // A 3-disk puzzle: System.out.println("3-Disk solution: "); solveHanoi(2, 0, 1); // A 4-disk puzzle: System.out.println("4-Disk solution: "); solveHanoi(3, 0, 1); } static void solveHanoi(int n, int i, int j) { // Create the three stacks. towers = new Stack[3]; for (int k = 0; k < 3; k++) { towers[k] = new Stack<Integer>(); } // Put disks 0,...,n on stack 0. for (int k = n; k >= 0; k--) { towers[0].add(k); } // Print the initial stack. printTowers(); // Now solve recursively. Note: this is the method below. solveHanoiRecursive(n, i, j); } static void solveHanoiRecursive(int n, int i, int j) { // Bottom-out. if (n == 0) { move(0, i, j); return; } int k = other(i, j); solveHanoiRecursive(n - 1, i, k); // Step 1. move(n, i, j); // Step 2. solveHanoiRecursive(n - 1, k, j); // Step 3. } static void move(int n, int i, int j) { // Pull out the top disk on stack i. int topVal = towers[i].pop(); // Put it on stack j. towers[j].push(topVal); // Print status. System.out.println("Towers after moving " + n + " from tower " + i + " to tower " + j); printTowers(); } static int other(int i, int j) { return 3-i-j; } static void printTowers() { for (int i = 0; i < towers.length; i++) { System.out.print("Tower " + i + ": "); if (!towers[i].isEmpty()) { for (Integer I : towers[i]) { System.out.print(" " + I); } } System.out.println(); } } }
From: http://www.seas.gwu.edu/~drum/cs1112/lectures/module9/module9.html
相关推荐
汉诺塔(Tower of Hanoi)是一个经典的递归问题,起源于19世纪的法国,由数学家爱德华·卢卡斯提出。这个谜题包含三根柱子和一堆大小不一的圆盘,玩家的目标是将所有圆盘从第一根柱子移动到第三根柱子,每次只能移动...
1.1 河内塔 The Tower Of Hanoi 1.2 平面上的直线 Lines In The Plane 1.3 约瑟夫问题 The Josephus Problem 2 和式 Sums 2.1 记号 Notation 2.2 和式和递归式 Sums And Recurrences 2.3 和式的处理 Manipulation ...
// Number of disks in the tower hanoi(numDisks, 'A', 'C', 'B'); // A, B and C are the rods } } ``` 在这个程序中,`hanoi`方法是递归函数,它接收三个参数:圆盘的数量、起始柱子、目标柱子和辅助柱子。当...
hanoi_tower.asm 算法 河内三盘三杆塔的算法如下: Let source = pole 1, spare = pole 2, destination = pole 3 Move the topmost (smallest) disk from pole 1 to pole 3 Move the 2nd larger disk from pole 1 to...
河内The Tower of Hanoi (also called the Tower of Brahma or Lucas' Tower and sometimes pluralized) is a mathematical game or puzzle. It consists of three rods, and a number of disks of different sizes ...
std::cout << "Enter the number of disks: "; std::cin >> num_disks; hanoi(num_disks, 'A', 'B', 'C'); return 0; } ``` 在这个例子中,`hanoi`函数实现了汉诺塔的递归解法。`main`函数获取用户输入的圆盘...
std::cout << "Enter the number of disks: "; std::cin >> num_disks; hanoi(num_disks, 'A', 'B', 'C'); return 0; } ``` 在这个程序中,`hanoi` 函数是递归主体,它接收三个参数:n 表示剩余需要移动的...
cout << "Enter the number of disks: "; cin >> n; hanoi(n, 'A', 'C', 'B'); return 0; } ``` 在这个程序中,`hanoi`函数接受三个参数:当前圆盘的数量(n)、起始柱子、目标柱子和辅助柱子。`main`函数读取...
汉诺塔(Hanoi Tower)是一个经典的递归问题,它涉及到三个柱子和一堆不同大小的圆盘。问题的目标是将所有圆盘从一个柱子(通常称为起始柱或A柱)移动到另一个柱子(目标柱或C柱),但每次只能移动一个圆盘,并且...
在"The blessed one tower"的压缩包文件中,可能包含了上述C语言代码的实现,供学习者参考和实践。通过阅读和运行这些代码,你可以更好地理解汉诺塔问题以及如何用C语言来解决它。这个过程不仅有助于提升你的编程...
// Number of disks in the problem hanoi(numDisks, 'A', 'B', 'C'); // A, B, and C represent the rods } } ``` 在这个程序中,`hanoi`函数接受三个参数,分别是源柱(fromRod)、中间柱(interRod)和目标柱...
Helping readers build efficient C data structures, this handbook explains how to apply data structures to enhance program execution. With a strong emphasis on ...37. Tower of Hanoi 38. Fibonacci Series
cout << "Moves for Tower of Hanoi with " ; hanoiTower(num_disks, 'A', 'C', 'B'); return 0; } ``` 在这个程序中,`hanoiTower`函数接收三个参数:表示盘子数目的整数n,起始柱子、目标柱子和辅助柱子的字符...
汉诺塔(Hanoi Tower)问题是一个经典的递归问题,源于19世纪由法国数学家爱德华·卢卡斯提出。VB(Visual Basic)是一种广泛使用的编程语言,用于创建Windows应用程序。在VB中实现汉诺塔问题,可以帮助我们更好地...
std::cout << "Enter the number of disks: "; std::cin >> numDisks; hanoiTower(numDisks, 'A', 'B', 'C'); return 0; } ``` 在这个程序中,`hanoiTower`函数实现了汉诺塔游戏的逻辑。`main`函数获取用户输入...
printf("Enter the number of disks: "); scanf("%d", &n); hanoiTower(n, 'A', 'C', 'B'); return 0; } ``` 在这个程序中,`main`函数首先询问用户输入盘子的数量,然后调用`hanoiTower`函数来解决问题。`...
汉诺塔(Tower of Hanoi)是一个经典的递归问题。游戏由三根柱子及不同大小的盘子组成,初始所有盘子自下而上按大小顺序依次穿在一根柱子上(即大盘在下,小盘在上)。游戏的目标是将所有盘子移到另一根柱子上,并且...
printf("Enter the number of disks: "); scanf("%d", &num_disks); if (num_disks ) { printf("Invalid number of disks. Please enter a positive integer.\n"); return 1; } hanoi_tower(num_disks, 'A'...
printf("Solution for Tower of Hanoi with %d disks:\n", num_disks); hanoi(num_disks, 'A', 'B', 'C'); return 0; } ``` 在这个程序中,`hanoi`函数实现了汉诺塔的递归解决方案。参数`n`表示盘子的数量,`...
printf("Tower of Hanoi with %d disks:\n", num_disks); hanoi(num_disks, 'A', 'C', 'B'); return 0; } ``` 在这个程序中,`hanoi`函数接受三个参数:表示起始柱、目标柱和辅助柱的字符,以及圆盘的数量。当...