一、实例说明
汉诺塔问题:传说在古代印度的贝拿勒斯圣庙里,安放了一块黄铜板,板上插了三根宝石柱,在其中一根宝石柱上,自上而下按由小到大的顺序串有64个金盘。这就是汉诺塔游戏。要求将左边柱子上的64个金盘按照下面的规则移到右边的柱子上。如图2-1所示:
规则:
a) 一次只能移一个盘子。
b) 盘子只能在三个柱子上存放。
c) 任何时候大盘不能放在小盘上面。
图2-1 汉诺塔示意图
二、基础知识点
汉诺塔是非常经典的关于递归程序的例子,读者如果将来要从事程序开发工作,则务必要掌握递归程序的设计方法。递归是程序设计中一个强有力的工具,有很多数学函数是递归定义的,比如大家熟悉的阶乘函数。
下面来简要分析一下汉诺塔问题是如何通过递归来解决的。
简化问题:
设盘子只有一个,则本问题可简化为a→b。
对于大于一个盘子的情况,逻辑上可分为两部分:第n个盘子和除n个以外的n-1个盘子。如果将除n以外的n-1个盘子看成一个整体,则要解决本问题,可按以下步骤:
a、将a杆上n-1个盘子借助于b先移到c杆; a→c (n-1,a,c,b)
b、将a杆上第n个盘子从a移到b杆; a→b
c、将c杆上n-1个盘子借助a移到b杆。 c→b (n-1,c,b,a)
三、技术要点
本例主要应用了if条件语句,主要把问题分为一个盘子的情况和大于一个盘子的情况。
语法:(两程序语句择一执行)
if(条件式)
{
程序语句1
}
else
{
程序语句2
}
递归程序的调用主要是通过在某函数内部再次调用本函数来实现。
四、实现步骤
首先新建一个类,命名为Hanio.java,在Hanio.java文件中键入下列代码:
public class Hanio {
public static void main(String args[]) {
//一共有两个盘子
byte n = 2;
// 定义三个杆子的名称
char a = ‘A’, b = ‘B’, c = ‘C’;
// 调用汉诺塔执行函数
hanio(n, a, b, c);
}
public static void hanio(byte n, char a, char b, char c) {
if (n == 1) { //如果只有一个盘子则直接把盘子从a 移到b
System.out.println(“move ” + a + ” to ” + b);
}
else { //超过一个盘子的情况
hanio( (byte) (n – 1), a, c, b); //将a杆上n-1个盘子借助于b先移到c杆
System.out.println(“move ” + a + ” to ” + b); //将a杆上第n个盘子从a移到b杆
hanio( (byte) (n – 1), c, b, a); //将c杆上n-1个盘子借助a移到b杆
}
}
}
五、归纳总结
如果一个问题能够简化成类似阶乘函数的形式,就可以用递归来实现,即在程序设计中,函数可以递归调用,主要利用了计算机的堆栈机制。递归函数结构清晰,程序易读,而且它的正确性容易得到证明。