汉诺塔是经典问题。具体表述为:由很多放置在三个塔座上的盘子组成的一个古老难题,所有盘子直径都是不同的,盘子中央都有一个洞使他们刚好可以放在塔座上。所有的盘子刚开始放在塔座A上面,这个难题的目标是将所有的盘子都从塔座A上移动到塔座C上,每一次只能移动一个盘子,并且任何一个盘子都不可以放在比自己小的盘子之上。如下图所示:
以三个盘子为例,如果以手工进行试验需要移动7次,先后顺序是:
Disk 1 from A to C
Disk 2 from A to B
Disk 1 from C to B
Disk 3 from A to C
Disk 1 from B to A
Disk 2 from B to C
Disk 1 from A to C
可以想象当A上盘子数目较大时就会出现非常复杂的操作,这时候人工几乎是不能完成的。仔细观察发现在移动四个盘子到C过程中必然有一个过程是B上有3个盘子,这时候只需要将最大的盘子从A移动到C即可。接下来就是将3个盘子从B移动到C的问题。这样分析可以使用递归来解决该问题。
也就是说当需要将A上面N个盘子按照规则转移到C塔座上时,可以转化为将(N-1)个盘子从B转移到A上即可,也就是说由N个盘子转移到C塔座上变成(N-1)个盘子从A转移到C上的问题,递归可以实现这个过程。
class HanoiTower
{
public static void doHanoiTower (int size,char source,char inner,char destSource)
{
if (size==1 )
{
System.out.println("disk1 from " +source+" to " +destSource);
return ;
}
else
{
doHanoiTower(size-1 , source, destSource,inner);
System.out.println("disk" +size+" from " +source+" to " +destSource);
doHanoiTower(size-1 , inner, source, destSource);
}
}
}
假设A上有四个盘子,则根据递归测试移动过程是:
public static void main (String[] args) {
int size=4 ;
HanoiTower.doHanoiTower(size, 'A' , 'B' , 'C' );
}
disk1 from A to B
disk2 from A to C
disk1 from B to C
disk3 from A to B
disk1 from C to A
disk2 from C to B
disk1 from A to B
disk4 from A to C
disk1 from B to C
disk2 from B to A
disk1 from C to A
disk3 from B to C
disk1 from A to B
disk2 from A to C
disk1 from B to C
用递归就可以通过少量代码解决看起来特别复杂的问题。