汉诺塔问题的递归算法
程序员文章站
2024-03-24 15:22:46
...
汉诺塔问题
相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。
移动必需遵守两个原则:
-
每次只能移动一个圆盘;
-
移动过程中,大圆盘不允许覆盖在小圆盘上。
解决算法
把n个盘子抽象地看作“两个盘子”,上面“一个”由1~n-1号组成,下面“一个”就是n号盘子。移动过程如下:
第一步:先把上面“一个”盘子以A基座为起点借助B基座移到C基座。
第二步:把下面“一个”盘子从A基座移到B基座。
第三步:再把C基座上的n-1盘子借助A基座移到B基座。
汉诺塔问题的算法hanoi描述如下:
hanoi (int n, char a, char b, char c)
1 if n>0 //0阶汉诺塔问题为递归结束条件
2 then { hanoi ( n-1, a , c , b );
3 print ( " Move disc “ , n. " from pile " , a , " to " b );
4 hanoi ( n-1 ,c , b, a ); }
程序设计如下:
全部源代码如下:
import java.util.*;
public class Demo1 {
public static void main(String[] args) {
Hanoi h=new Hanoi(4);
h.han(4,h.a,h.b,h.c);
h.print();
System.out.println("\n"+"总共移动"+h.getM()+"次");
}
}
class Hanoi{
Vector<String> a=new Vector<String>();//a柱
Vector<String> b=new Vector<String>();//b柱
Vector<String> c=new Vector<String>();//c柱
int n;//汉诺塔的阶数
static long M=0;//最少移动的次数
//初始化汉诺塔a柱上的盘子
Hanoi(int n){
this.n=n;
for(int i=0;i<n;i++){
a.add(i, (n-i)+"");
}
}
public void han(int n,Vector<String> x,Vector<String> y,Vector<String> z){
if(n>0){
han(n-1,x,z,y);
print();
//把x柱上的最后一个移到y柱
y.add(x.get(x.size()-1));
x.remove(x.size()-1);
M++;
han(n-1,z,y,x);
}
}
//返回总次数
long getM(){
return M;
}
//打印移动的每一步过程
void print(){
System.out.print("\n"+"a:");
for(int i=0;i<a.size();i++){
System.out.print(a.get(i)+" ");
}
System.out.print("\n"+"b:");
for(int i=0;i<b.size();i++){
System.out.print(b.get(i)+" ");
}
System.out.print("\n"+"c:");
for(int i=0;i<c.size();i++){
System.out.print(c.get(i)+" ");
}
}
}
运行结果如下: