`

The Tower of Hanoi

 
阅读更多

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.
We will solve the problem using (of course) recursion:
  • 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.

       

  • 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

分享到:
评论

相关推荐

    HanNuoTa.zip_C#汉诺塔_csharp 汉诺塔_tower of hanoi_汉诺塔

    汉诺塔(Tower of Hanoi)是一个经典的递归问题,起源于19世纪的法国,由数学家爱德华·卢卡斯提出。这个谜题包含三根柱子和一堆大小不一的圆盘,玩家的目标是将所有圆盘从第一根柱子移动到第三根柱子,每次只能移动...

    具体数学 - Concrete Mathematics (1&2合集)

    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 ...

    Hanoi-Tower:著名的河内塔的 Java 程序

    // Number of disks in the tower hanoi(numDisks, 'A', 'C', 'B'); // A, B and C are the rods } } ``` 在这个程序中,`hanoi`方法是递归函数,它接收三个参数:圆盘的数量、起始柱子、目标柱子和辅助柱子。当...

    汉诺塔java源码-tower_of_hanoi:MIPS汇编语言(ECE151)中的河内塔实现

    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...

    funny-code:有有趣的问题的工具,例如河内塔

    河内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 ...

    基础的C++程序hanoi

    std::cout &lt;&lt; "Enter the number of disks: "; std::cin &gt;&gt; num_disks; hanoi(num_disks, 'A', 'B', 'C'); return 0; } ``` 在这个例子中,`hanoi`函数实现了汉诺塔的递归解法。`main`函数获取用户输入的圆盘...

    Hanoi-Tower.rar_著名的汉诺塔

    std::cout &lt;&lt; "Enter the number of disks: "; std::cin &gt;&gt; num_disks; hanoi(num_disks, 'A', 'B', 'C'); return 0; } ``` 在这个程序中,`hanoi` 函数是递归主体,它接收三个参数:n 表示剩余需要移动的...

    c++实现hanoi

    cout &lt;&lt; "Enter the number of disks: "; cin &gt;&gt; n; hanoi(n, 'A', 'C', 'B'); return 0; } ``` 在这个程序中,`hanoi`函数接受三个参数:当前圆盘的数量(n)、起始柱子、目标柱子和辅助柱子。`main`函数读取...

    汉诺塔 (hanoi) c++

    汉诺塔(Hanoi Tower)是一个经典的递归问题,它涉及到三个柱子和一堆不同大小的圆盘。问题的目标是将所有圆盘从一个柱子(通常称为起始柱或A柱)移动到另一个柱子(目标柱或C柱),但每次只能移动一个圆盘,并且...

    The blessed one tower_汉诺塔问题_

    在"The blessed one tower"的压缩包文件中,可能包含了上述C语言代码的实现,供学习者参考和实践。通过阅读和运行这些代码,你可以更好地理解汉诺塔问题以及如何用C语言来解决它。这个过程不仅有助于提升你的编程...

    hannuota.rar_Hanoi_java 汉诺塔

    // Number of disks in the problem hanoi(numDisks, 'A', 'B', 'C'); // A, B, and C represent the rods } } ``` 在这个程序中,`hanoi`函数接受三个参数,分别是源柱(fromRod)、中间柱(interRod)和目标柱...

    Data.Structures.and.Algorithms.USING.C

    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

    汉诺塔问题c++递归解法

    cout &lt;&lt; "Moves for Tower of Hanoi with " ; hanoiTower(num_disks, 'A', 'C', 'B'); return 0; } ``` 在这个程序中,`hanoiTower`函数接收三个参数:表示盘子数目的整数n,起始柱子、目标柱子和辅助柱子的字符...

    VB Hanoi问题

    汉诺塔(Hanoi Tower)问题是一个经典的递归问题,源于19世纪由法国数学家爱德华·卢卡斯提出。VB(Visual Basic)是一种广泛使用的编程语言,用于创建Windows应用程序。在VB中实现汉诺塔问题,可以帮助我们更好地...

    汉诺塔C++ 实现

    std::cout &lt;&lt; "Enter the number of disks: "; std::cin &gt;&gt; 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`函数来解决问题。`...

    C++ 小程序

    汉诺塔(Tower of Hanoi)是一个经典的递归问题。游戏由三根柱子及不同大小的盘子组成,初始所有盘子自下而上按大小顺序依次穿在一根柱子上(即大盘在下,小盘在上)。游戏的目标是将所有盘子移到另一根柱子上,并且...

    c语言实现的汉诺塔演示程序.zip

    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'...

    C语言-汉诺塔问题解决源码.zip

    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`函数接受三个参数:表示起始柱、目标柱和辅助柱的字符,以及圆盘的数量。当...

Global site tag (gtag.js) - Google Analytics