功能
解决经典的汉诺塔圆盘移动问题
根据用户输入的圆盘数量计算圆盘移动总次数,输出每一步的圆盘移动方法并额外输出圆盘移动总次数。
汉诺塔问题
汉诺塔源于印度神话,大梵天创造世界时造了三根柱子,其中第一根自底向上叠放这64片从大到小互不相同的黄金圆盘,大梵天命令婆罗门借助于第三根柱子把圆盘按原始大小与顺序重新摆放在第二根柱子上。并规定,在小盘上不能放大盘,在三根柱子之间一次只能移动一个圆盘。移动要遵守如下规则:
(1)n个盘子标记为1,2,3,…,n,而三哥柱子分别标记为A,B,C;
(2)任何时候都不能把大盘子放在小盘子上;
(3)初始状态时,所有盘子都放在A柱子上;
(4)每次只移动一个盘子,并且只能移动最顶端的盘子。
问题分析
汉诺塔问题移动次数统计
有n个盘子,需要从A借助于B移动到C,移动的次数是move(n):
当n=1时,只需要移动1次
当n=2时,
先走个将n-1个盘子从A借助于B移动到C的次数,即:move(n-1)
再将A上的最底下的那个盘子直接移动到C,即1次
再走个将B上的n-1个盘子借助A移动到C的次数,即:move(n-1)
即当n>1时,走的次数是2*move(n-1)+1
汉诺塔问题移动步骤输出
a存放起始柱,b存放辅助柱、c存放目标柱 (1)当 n == 1时,直接将盘子从 A 移动到 C
(2)当 n > 1时,可以拆分成3大步骤
①将 n– 1 个盘子从 A 借助 C 移动到 B
②将编号为 n 的盘子从 A 借助 B 移动到 C
③将 n– 1 个盘子从 B 借助 A 移动到 C
代码部分
代码
1. package priv.work.c2;
2. import java.util.Scanner;
3. public class HanoiProblem{
4. public static void main(String[] args) {
5. Scanner input = new Scanner(System.in);
6. System.out.println("请输入圆盘的数量:");
7. int num = input.nextInt();
8. System.out.println(num+"个盘子移动总次数为:"+movestep(num));
9. System.out.println(num+"个盘子移动次序为:");
10. hanoiTower(num, 'A', 'B', 'C');//起始柱、辅助柱、目标柱默认为A、B、C
11. }
12. //实现汉诺塔问题移动次数统计
13. /*
14. 有n个盘子,需要从A借助于B移动到C,移动的次数是move(n):
15. 当n=1时,只需要移动1次
16. 当n=2时,
17. 先走个将n-1个盘子从A借助于B移动到C的次数,即:move(n-1)
18. 再将A上的最底下的那个盘子直接移动到C,即1次
19. 再走个将B上的n-1个盘子借助A移动到C的次数,即:move(n-1)
20. 即当n>1时,走的次数是2*move(n-1)+1
21. */
22. public static int movestep(int n){
23. if(n==1){
24. return 1;
25. }else{
26. return 2*movestep(n-1)+1;
27. }
28. }
29. //汉诺塔问题实现步骤输出
30. //a存放起始柱,b存放辅助柱、c存放目标柱
31. /*
32. (1)当 n == 1时,直接将盘子从 A 移动到 C
33. (2)当 n > 1时,可以拆分成3大步骤
34. ①将 n– 1 个盘子从 A 借助 C 移动到 B
35. ②将编号为 n 的盘子从 A 借助 B 移动到 C
36. ③将 n– 1 个盘子从 B 借助 A 移动到 C
37. */
38. public static void hanoiTower(int num, char a, char b, char c) {
39. if(num == 1) {
40. System.out.println("第" + num + "个盘" + "从" + a + "移动到" + c);
41. }else {
42. hanoiTower(num - 1, a, c ,b);
43. System.out.println("第" + num + "个盘" + "从" + a + "移动到" + c);
44. hanoiTower(num - 1, b, a, c);
45. }
46. }
47. }