汉诺塔核心代码清晰详解--中秋巨献

版权声明:------------转载请标明链接.博客内容仅供参考,一切以官方文档为准!------------ https://blog.csdn.net/wabiaozia/article/details/82822888

最近XXX原因,比较久没写博客了,正好这会有点空就想写点东西。本来想写图相关算法,但是图相关东西比较多也比较复杂,一时也很难全面的写出来,即使写出来,也太零星反而更增加了读者的困惑。忽然想起来前两天有网友私信,说基础的递归如斐波那契算法能写出来,但是遇到稍微复杂点的就乱了,他看到小甲鱼教的汉诺塔算法懂原理了,但是看代码时还是感觉似懂非懂,理解的不是特别清晰。这个问题不大,几分钟就可以写好,正好适合现在写。博客链接:https://blog.csdn.net/wabiaozia/article/details/82822888

其实写递归时最简单的办法是递推出递归的公式,然后根据公式写递归。不过实际情况是,工作了不少年后不碰数学,对归纳公式有些抵触,碰到递归时更倾向于直接就开干,管他可不可以归纳出表达式。直接开干递归其实也有些技巧,防止你出现 '写代码时写着写着就乱了' 的问题。

如何设计递归算法:

1. 子问题须与原始问题为同样的事,且更为简单;
2. 不能无限制地调用本身,须有个出口,化简为非递归状况处理

递归算法更详细的介绍看:

https://www.bilibili.com/video/av7398130  用二进制来解汉诺塔问题

https://www.bilibili.com/video/av2975983/?p=34 

https://blog.csdn.net/wabiaozia/article/details/82822888

我这里不介绍如何设计算法,直接开干汉诺塔。

     什么是汉诺塔???汉诺塔hanoi:abc三根柱子,把a柱子上的n个盘子移动到c柱子上,每次只能移动一个盘子,移动的时候小盘子不能放在大盘子上。

  •  把a柱子上的盘子看成两份,n作为一份,其余的n-1作为一份。把n-1作为一个整体移动到b柱子上(借助c柱子,c柱子作为中间站), 把   a柱子上最大的n盘子移到c柱子上。
  •  然后把其余的b柱子上的n-1个盘子作为一个整体,借助a柱子(a柱子作为中间站),移动到c柱子上。
  •  由于一次只能移动一个盘子,不能一次移动n-1个盘子,所以要把n-1个盘子再拆为两份,n-1为一份,其余的为一份。以此类          推。。。   如果还不能理解可以去看上面第二个视频。

前提:把盘子从a柱子移动到c柱子,b柱子作为中间站。则a为起点,c为落点,b为中间站。

扫描二维码关注公众号,回复: 3369477 查看本文章

理解汉诺塔代码的核心在下面两句话(私信网友糊涂的点估计在这里):

  •  每次这个方法传进来4个参数,第0个位置盘子数,第一个位置是起点,第二个位置是中间站,第三个位置是落点。见下图标示。
  •  传进来的abc放在hanoi方法参数的不同位置,即可改变下次执行的起点中间站落点。举例1:hanoi(n,a,c,b) 下次执行时即a为起点,c为中间站,b为落点 。 举例2:hanoi(n,b,a,c) 下次执行时b为起点,a为中间站,c为落点。详见代码里注释

public static void main(String[] args) {
		int n=5;
		Hannii hannii = new Hannii();
		String a = "a";
		String b="b";
		String c="c";
		hannii.hanoi(n,a,b,c);
	}
	
//	前提:把盘子从a柱子移动到c柱子,b柱子作为中间站。则a为起点,c为落点,b为中间站。
//	*****注意****//我的博客 https://blog.csdn.net/wabiaozia/article/details/82822888
//	1 这个方法传进来4个参数,第0个位置盘子数,第一个位置是起点,第二个位置是中间站,第三个位置是落点。
//	2 传进来的abc放在hanoi方法参数的不同位置,即可改变下次执行的起点中间站落点。举例1:hanoi(n,a,c,b) 下次执行时即a为起点,c为中间站,b为落点 。
//	举例2:hanoi(n,b,a,c) 下次执行时b为起点,a为中间站,c为落点。
	private void hanoi(Integer n, String a, String b, String c) {
		if (n==1) {
			System.out.println(a+"----->----->"+c);
		}else {
//			盘子从a移动到b,用c作为中间站。见举例1
//			解释下把传进来的参数怎么放:这次递归的起点即hanoi方法的第一个参数,怎么放?把参数里传进来的a放到第一个参数位置。   
//			这次递归的落点即hanoi方法的第二个参数,怎么放?把参数里传进来的 b放到第三个位置。
//			这次递归的中间站即hanoi方法的第三个参数,怎么放?把 参数传进来的 c放到第二个位置。
			hanoi(n-1, a, c, b);     
			//我的博客 https://blog.csdn.net/wabiaozia/article/details/82822888
			move(a,c);
			
//			盘子从b移动到c,用a作为中间站,见举例2。这轮递归起点:参数里传进来的from。 这轮递归的中间站: 参数传进来的 to。  这轮递归的落点:参数里传进来的 inner。
			hanoi(n-1, b, a, c);
		}
		
	}

	private void move(String a, String c) {
		System.out.println(a+"----->"+c);
	}
	 

转载请标明连接:https://blog.csdn.net/wabiaozia/article/details/82822888

我博客所有文章链接:https://blog.csdn.net/wabiaozia

猜你喜欢

转载自blog.csdn.net/wabiaozia/article/details/82822888