递归经典问题——汉诺塔

学习数据结构就一定会遇到递归,遇到递归就一定会碰到汉诺塔问题,在我的学习生涯中这三个字是曾经一直笼罩在我心头的阴影——代码太简洁,完全看不懂我靠出题人简直是ZZ,为什么不能把A、C柱子的名字换一下,这多简单! 以至于糊弄糊弄考试过了到现在都没弄懂

这段时间重拾《数据结构》这个破塔又来了!巨魔兄弟说的对,消除恐惧的最好办法就是面对恐惧,看不懂我就百度奥力给,弄了半天终于算是推了这座高地塔————

汉诺塔

汉诺塔(Tower of Hanoi),又称河内塔,源于印度一个古老传说的益智玩具。

大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。

实际规则如下

  1. 有三根杆子A,B,C;其中A杆上有从上到下由小到大摆放的若干碟子
  2. 每次移动一块碟子,小的只能叠在大的上面
  3. 把所有碟子从A杆全部移到C杆上

首先我们知道当A柱子上只有1个盘子的时候,只要一步:A => C;

A柱子上有2个盘子的时候,只需要三步( A => B;A => C; B => C)就能结束。

当A柱子上的盘子数量特别多(比如有64个)的时候,拆开看的步骤也许很麻烦,但是分析一下,无论多少个盘子,最下面的盘子永远是只会移动一次:A => C,也就是说只要把最上面的63个盘子看作一个,那么步骤其实和2个盘子是一样的:先移动最上面的63个盘子,此时再把63个盘子分成1+62个盘子…如此往复就到了最初的只有1个盘子

这样就完成了递归的两个条件:

  • 把大问题拆成小问题,把小问题拆成更小的问题:n=(n-1)+1…64=63+1;63=62+1;62=61+1…3=2+1;2=1+1
  • 可直接求解的最小问题:1个盘子的移动方法

由此构造Hanoi方法(Java):

Hanoi(int n,char a,char b,char c){    //需要四个参数:n-盘子的数量  a-一号位  b-二号位  c-三号位
	if(n == 1){
		printf(n + "号盘子从" + a + "移动到" + c);	//始终操作一号位和二号位的柱子,可以看出最上面的盘子编号是1
	}else{
		Hanoi(n-1,A,C,B);	//当n=2时,会执行 printf(n + "号盘子从" + a + "移动到" + c);也就是:1号盘子从A移动到B
		printf(n + "号盘子从" + a + "移动到" + c);
		Hanoi(n-1,B,A,C);
	}
}

主函数中:

Hanoi(64,A,B,C);	//abc代表三个放柱子的空位,ABC表示柱子的名称

这段程序尽管代码简洁漂亮,但是理解起来稍微吃力,不过只要理解了这段代码,递归也就被理解的八九不离十了!

更多递归相关知识移步【Java数据结构2——递归】,欢迎大佬指正错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值