汉诺塔问题的解决思想

        汉诺塔问题是法国数学家编写的一个古老传说:在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教的主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。   

        这个问题是一个典型的递归问题,通过多重递归,最后简化为对一个盘子的操作,我们不需要关心程序具体的细节,只需要关注大体的步骤,就像“把大象装进冰箱需要分几步”这个问题,只需要三步:打开冰箱、把大象放进去、关上冰箱。汉诺塔问题也是如此,每一块金片移动到目的地,只需要三步。下面我们就来讨论,具体该怎么去思考这个问题。

                   《汉诺塔问题的解决思想》     

我们将三根柱子用左柱,中柱,右柱表示  

如果只有一块金片的话,我们要怎么处理呢,是不是可以这样想:将金片从左柱移动到右柱就可以了

那么继续考虑这种情况:有两块金片的时候,要怎么处理呢,我们把第一块金片放到中柱上,再把左柱底下的金片移动到右柱上,再将中柱的金片移动到右柱上,就达成了目标

思考完两片柱子的移动之后,其实我们已经有一些思路了,假如有n块(n>=2)金片,我们以四块为例,那么我们的大步骤是这样的:

《汉诺塔问题的解决思想》

1.将最底下的一片看作一片,将上面的3片(n-1)片看作一片

2.将n-1片金片通过右柱的帮助,最终移动到中柱子上,不需要具体关心如果实现,我们只要这么想即可

3.将最底下的一片通过中柱的帮助放到右柱上(尽管不需要中柱的帮助,我们还是这么说)

4.那么就会变成这样的情况:

《汉诺塔问题的解决思想》

最右边的金片是已经不需要移动的,也不会对我们造成影响,我们在心理就当没有这块金片,那么现在问题就变成了:将三块金片从中柱移动到右柱上,这个场景是不是很相似呢,我们不需要考虑三个柱子的位置,只需要看到:起始位置,中间位置,目标位置。那么跟刚才的问题就是一样的,刚才是需要把四块金片从起始位置,通过中间位置的帮助,到达目标位置,现在化繁为简,变成三块了,那么我们如果继续重复这样的思路:把最底下的看作一块,剩余的两块看作一块,再重复三个步骤:

1.把底下的看作一块,把上面的其余金片看作一块

2.将上面的一大块金片通过右柱的帮助,最终移动到左柱子上,不需要具体关心如果实现,我们只要这么想即可

3.将最底下的一片通过左柱的帮助放到右柱上(尽管不需要中柱的帮助,我们还是这么说)

4.那么又变成了这样的情况:

《汉诺塔问题的解决思想》

这样就变成了两个金片的移动问题了,可想而知再次重复上面的步骤,我们就可以化做一个金片的移动问题,那么一片金片的移动就只是搬过去就好了。

通过上面的分析我们可以看出来:任何数量的金片移动,都可以一步步解析为一块金片的移动,而我们能够清晰地描述出一块金片的移动过程,那么问题就可以抽象地描述出来了

下面是用Java的实现:

public class HanoiDemo {

	public static void main(String[] args) {
		hanoi(20,"左柱","中柱","右柱");
	}
	
	
	//方法理解:将n块金片,从a盘子上,通过b盘子的帮助,移动到c盘上
	static int counter =0;
	public static void hanoi(int n,String a,String b,String c) {
		if(n==1) {
			System.out.println("将盘子从"+a+"移动到"+b+"上,第"+counter+"次移动");
			counter++;
		}
		if(n>=2) {
			hanoi(n-1,a,c,b);
			hanoi(1,a,b,c);
			hanoi(n-1,b,a,c);
		}
	}

}

方法就只有短短的十行,重要的还是对于思想的理解,如果对原理了解透了,计算机可以帮我们做更多的事

    原文作者: 汉诺塔问题
    原文地址: https://blog.csdn.net/baiyang_/article/details/79735282
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞