汉诺塔递归算法Java实现

有三根相邻的柱子,标号为A,B,C,A柱子上从下到上按金字塔状叠放着n个不同大小的圆盘,要把所有盘子一个一个移动到柱子B上,
并且每次移动同一根柱子上都不能出现大盘子在小盘子上方,
请问至少需要多少次移动,设移动次数为H(n)。

与这个问题相似的其他故事传说

和汉诺塔故事相似的,还有另外一个印度传说:舍罕王打算奖赏国际象棋的发明人──宰相西萨·班·达依尔。
国王问他想要什么,他对国王说:“陛下,请您在这张棋盘的第1个小格里赏给我一粒麦子,在第2个小格里给2粒,第3个小格给4粒,以后每一小格都比前一小格加一倍。
请您把这样摆满棋盘上所有64格的麦粒,都赏给您的仆人吧!”国王觉得这个要求太容易满足了,
就命令给他这些麦粒。当人们把一袋一袋的麦子搬来开始计数时,国王才发现:就是把全印度甚至全世界的麦粒全拿来,也满足不了那位宰相的要求。
那么,宰相要求得到的麦粒到底有多少呢?总数为

回到问题本身,如何求解?

规则:每次移动,同一根柱子上都不能出现,小盘在大盘上方;

现在假设:A柱有三个盘,从上到下依次编号:1、2、3;

要将三个盘子,全部移动到B柱中;

其中必定存在的状态:

 A:3,B:      (没有盘子),C:1、2;

整个问题:可以必然可以分解为下面的3过程:

1、将A柱2个盘子移动到C柱;

2、将A柱1个盘子移动到B柱;

3、将C柱2个盘子移动到B柱;

将A柱3个盘子借助C柱移动到B柱;

用函数表示:f(3,A,B,C);

1、将A柱2个盘子移动到C柱;

f(2,A,C,B);

2、将A柱1个盘子移动到B柱;

f(1,A,B,C)->将A柱盘子移动到B柱;

3、将C柱2个盘子借助A柱移动到B柱;

f(2,C,B,A);

函数关系式:f(3,A,B,C)=f(2,A,C,B)+f(1,A,B,C)+f(2,C,B,A);

推广到n的情况:

f(n,A,B,C)=f(n-1,A,C,B)+f(1,A,B,C)+f(n-1,C,B,A);

代码实现:

	/**A/B/C分别代表三个柱子,n代表A柱子上的盘子数*/
	public void f(int n,char A,char B,char C) {
		
		if(n == 1) {
			System.out.println("move:"+A+"->"+B);
			return;
		}		
		f(n-1,A,C,B);
		f(1,A,B,C);
		f(n-1,C,B,A);		
	}

猜你喜欢

转载自blog.csdn.net/m0_37550986/article/details/80639445