汉诺塔问题的递归算法

汉诺塔问题


相传在古印度圣庙中,有一种被称为汉诺塔(Hanoi)的游戏。该游戏是在一块铜板装置上,有三根杆(编号A、B、C),在A杆自下而上、由大到小按顺序放置64个金盘。游戏的目标:把A杆上的金盘全部移到C杆上,并仍保持原有顺序叠好。

移动必需遵守两个原则:

  1. 每次只能移动一个圆盘;

  2. 移动过程中,大圆盘不允许覆盖在小圆盘上。

解决算法


把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)+" ");
		}
		
	}
}

运行结果如下:


猜你喜欢

转载自blog.csdn.net/qq_34399639/article/details/82560149