数据结构:递归应用---Hanoi问题(汉诺塔)

问题描述:

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

 

分析:

尽量把问题往简单考虑 这样一个思路:1.如果n等于1 直接将其移到C上  ;

2.如果n>2 则就需要B柱子来做辅助  A:(如何来进行移动 同时还要保证上面的圆盘不能大于下面的圆盘 )我们先把A圆盘上的1到n-1的圆盘移到B柱子上 再把n圆盘移到C柱子上,这里我们就需要一个将C柱子作为辅助

B.我们现在把3看成和c柱子已经融为一起了 这个问题就变成了 把b柱子上的圆盘移到C上去 要求上面的圆盘不能大于下面的圆盘

如何实现其步骤和A步骤是一样的 思路是一样的 为什么这么说 因为第二次所找的辅助柱子会有所不同 我们第一次将1-n-1的圆盘移动到B柱子上是以C作为辅助 那么我们现在的问题是把B柱子上的1-n-1的圆盘移到哪儿?当然最终是要移到C盘上。辅助又应该是谁呢?如果还是将C作为辅助可行吗?答案时不行的。我们可以这样思考 我们的目的就是要把剩下的1-n-1移到我们的C盘上  这是就需要A来做为我们的辅助盘l

然后我们又可以进行AB这样的操作 所以 大致思路就是这样


public class Hanoi {
	static int count = 0;

	public static void hanoi(int n, char a, char b, char c) {
		// 如果a柱子上只有一个圆盘 则就直接移动到c盘上
		count++;
		if (n == 1) {
			move(a, n, c);
			// return;
		} else {
			// 进行递归
			// 将a 1到n-1圆盘移到b上 c作为辅助
			hanoi(n - 1, a, c, b); // 步骤A
			move(a, n, c); // 将n由a移到c
			// 将b 1到n-1圆盘移到c盘上 a作为为辅助
			hanoi(n - 1, b, a, c); // 步骤B
		}
	}

	// 移动圆盘
	private static void move(char a, int n, char c) {
		System.out.println("移动:" + n + "  " + a + "——>" + c);

	}

	public static void main(String[] args) {
		char a = 'A';
		char b = 'B';
		char c = 'C';
		hanoi(5, a, b, c);
		System.out.println(count);
	}
}

  运行结果:

移动:1  A——>C
移动:2  A——>B
移动:1  C——>B
移动:3  A——>C
移动:1  B——>A
移动:2  B——>C
移动:1  A——>C
移动:4  A——>B
移动:1  C——>B
移动:2  C——>A
移动:1  B——>A
移动:3  C——>B
移动:1  A——>C
移动:2  A——>B
移动:1  C——>B
移动:5  A——>C
移动:1  B——>A
移动:2  B——>C
移动:1  A——>C
移动:3  B——>A
移动:1  C——>B
移动:2  C——>A
移动:1  B——>A
移动:4  B——>C
移动:1  A——>C
移动:2  A——>B
移动:1  C——>B
移动:3  A——>C
移动:1  B——>A
移动:2  B——>C
移动:1  A——>C
31

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值