算法 汉诺塔-java详解

第一次看到这个算法时,很懵逼,是在栈那里。想了半天没想到半点跟栈有关系的解法。最后看了答案,是用的递归。但是看了答案还是很懵逼,下面就是博主自己对汉诺塔的一些了解。


有三根木桩,第一根上有n个盘子,最底层的盘子最大,最上层的盘子最小。汉诺塔问题就是将所有的盘子从第一根木桩开始,以第二根木桩为桥梁,全部搬到第三根木桩。

不过在搬动时,尚须遵守以下游戏规则:

1、每次只能从最上面移动一个盘子(乍一看,尼玛还真是栈)

2、任何盘子可以从任何木桩搬到其他木桩。

3、直径较小的盘子永远必须放在直径较大的盘子之上。


下面的分析来源于其他博主

如果n=1,则将圆盘从A直接移动到C。
如果n=2,则:
1.将A上的n-1(等于1)个圆盘移到B上;
2.再将A上的一个圆盘移到C上;
3.最后将B上的n-1(等于1)个圆盘移到C上。
  如果n=3,则:
A. 将A上的n-1(等于2,令其为n`)个圆盘移到B(借助于C),步骤如下:
(1)将A上的n`-1(等于1)个圆盘移到C上。
(2)将A上的一个圆盘移到B。
(3)将C上的n`-1(等于1)个圆盘移到B。
B. 将A上的一个圆盘移到C。
C. 将B上的n-1(等于2,令其为n`)个圆盘移到C(借助A),步骤如下:
(1)将B上的n`-1(等于1)个圆盘移到A。
(2)将B上的一个盘子移到C。
(3)将A上的n`-1(等于1)个圆盘移到C。
   到此,完成了三个圆盘的移动过程。
    从上面分析可以看出,当n大于等于2时,移动的过程可分解为三个步骤:
第一步  把A上的n-1个圆盘移到B上;
第二步  把A上的一个圆盘移到C上;
第三步  把B上的n-1个圆盘移到C上;其中第一步和第三步是类同的。

其实看到这里基本可以看出规律,就是用递归。

设盘数为n,

当n=1时,直接将盘从一号木桩转移到3号木桩

当n=2时,转移顺序:1号->2号,2号->3号,2号->3号

重点就是当n>=3时,将第n个盘和上面的n-1个盘分离,整体看起来就剩下2个部分:n,(1~n-1);后面递归就是将(1~n-1)分离成(1~n-2)和(n-1)...以此递归。

递归方法体面放四个参数,n(层数),p1(一号桩),p2(二号桩),p3(三号桩)。每次递归(一号桩)是初始位置,(三号桩)为目标位置

那么n>=3时递归顺序便是:

先创建方法:public static void solve(int n,int p1,int p2,int p3){....}

(1)将(1~n-1)分离放到(二号桩),这里就是(1~n-1)在(一号桩)(初始位置),(二号桩)就是(三号桩)(目标位置)

第一次递归代码:solve(n-1,p1,p3,p2),说到底,真正有用的参数只有3个,第1个、第2个、第4个;第三个参数就是打酱油的,你也可以认为是借助工具。

(2)将n转移到(三号桩),按规矩,应该是solve(n-1,p1,p2,p3);但是这里写了第一是个死循环,第二,n转移没有借助p2,所以默认他很自觉,自己到三号桩,直接

System.out.println("从"+p1+"移动到"+p3);

(3)将(1~n-1)从(二号桩)转移到(三号桩),方法看懂(1)的这里自然懂

solve(n-1,p2,p1,p3);


那么这题完整解法就是:

import java.util.Scanner;

public class Hanoi {
	
	//p1为初始盘,p3为目标盘
	public static void solve(int n,int p1,int p2,int p3){
		if(n==1)
			System.out.println("从"+p1+"移动到"+p3);
		else{
			solve(n-1,p1,p3,p2);
			System.out.println("从"+p1+"移动到"+p3);
			solve(n-1,p2,p1,p3);
		}
	}
	
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		solve(n,1,2,3);
	}
}

  • 11
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值