Hanoi塔

  Hanoi塔(汉诺塔)问题如下图:

  设X Y Z为三个塔座,开始时再塔座上有n个圆盘,他们自上而下由小到大的叠放着,编号依次为1,2,...,n,现在要求将塔座X上的这一叠圆盘移到塔座Z上,并按同样顺序叠放,在移动时要遵循以下规则:

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

  (2)任何时刻都不允许将较大的圆盘放在较小的圆盘之上;

  (3)在满足(1)(2)两个条件的情况下,可以将圆盘放在任意塔座上。

  这个问题有两种解决方法:一个是利用递归的方法,易于理解,但空间和时间复杂度较高;另一种还是比较简单的方法,但理解起来较困难些。

  1.先说下递归的方法:要将1到n个圆盘放在Z上,可以分三步走,先将1到n-1个圆盘按照规则放在过渡塔座Y上,再把圆盘n放到Z的底部,最后再把Y上的1到n-1个圆盘再按规则放到Z中圆盘n上。而对于1到n-1圆盘的移动又可以同理递归到第1到n-2个圆盘的操作上,如此类推:

  很自然的可以得到如下程序:

/*
 *@param n 移动第1到n个圆盘
 *@param src 从塔座src上移动
 *@param des 移动到des塔座上
 *@param t 以t塔座为过渡
 */
public void hanoi(int n, int src, int des, int t){
	if(n > 1){
		hanoi(n - 1, src, t, des);
		move(n, src, des);	//将第n个圆盘从X移动到Z
		hanoi(n - 1, t, des, src);
	}else{
		move(n, src, des);
	}
}

  2.另一种非递归方法:假设塔座X,Y,Z排成一个三角形:Z -> Y -> X -> Z。其中X是源塔座,Z是目的塔座。构成一个循环的三角形。在移动圆盘的过程中,若是奇数词移动,则将最小的圆盘移动到其所在塔座的下一个塔座上;若是偶数次移动,则保持最小的圆盘不懂,而其他两个塔座之间,将较小的圆盘移动到另一塔座上。

原文地址:https://www.cnblogs.com/wu8685/p/1910518.html