递归法实现汉诺塔问题
这里的汉诺塔问题稍加改动:从“左”不能直接到“右”,必须先从“左”到“中”,再从“中”到“右”;从“右”到“左”同理;即只能在相邻的柱子间移动。
思路:
process(int num, String from, String to)函数,实现了第num块,从from柱子到to柱子的移动过程- 移动分为两类,相邻柱子的移动,不相邻柱子的移动(如果是传统的汉诺塔问题则不用如此分类)
- 相邻柱子的移动:
从"左"到"中",从"右"到"中",从"中"到"左",从"中"到"右"
- 上面的
num - 1层,从from移到另一个柱子,即除了from和to的另一根柱子
- 然后第
num块从from到to
- 上面的
num - 1层从另一个柱子到to- 不相邻柱子的移动:
从"左"到"右",从"右"到"左"
- 上面的
num - 1层从from到to
- 第
num块,从from移到middle
- 然后第
num - 1块从to到from
- 第
num块,从middle移到to
- 上面的
num - 1层从from到to
package com.lilydedbb;
/**
* Created by dbb on 2016/12/24.
*/
public class HanoiProblemByRecursion {
private static String left = "left ";
private static String mid = "middle";
private static String right = "right ";
public static int hanoiProblem(int num){
if (num < 1)
return 0;
return process(num, left, right);
}
// 返回的是步数
public static int process(int num, String from, String to){
// 只有一个的时候
if(num == 1){
if(from.equals(mid) || to.equals(mid)){
System.out.println("move 1 from " + from + " to " + to);
return 1;
}else{
System.out.println("move 1 from " + from + " to middle");
System.out.println("move 1 from middle to " + to);
return 2;
}
}
// 从"左"到"中",从"右"到"中",从"中"到"左",从"中"到"右"
if(from.equals(mid) || to.equals(mid)){
String another = (from.equals(left) || to.equals(left)) ? right : left;
int part1 = process(num - 1, from, another);
int part2 = 1;
System.out.println("move " + num + " from " + from + " to " + to);
int part3 = process(num - 1, another, to);
return part1 + part2 + part3;
} else { // 从"左"到"右",从"右"到"左"
int part1 = process(num - 1, from, to);
int part2 = 1;
System.out.println("move " + num + " from " + from + " to middle");
int part3 = process(num - 1, to, from);
int part4 = 1;
System.out.println("move " + num + " from middle to " + to);
int part5 = process(num - 1, from, to);
return part1 + part2 + part3 + part4 + part5;
}
}
}
测试程序及测试结果如下:
int steps = HanoiProblemByRecursion.hanoiProblem(2);
System.out.println("The Minimum step is " + steps);
move 1 from left to middle
move 1 from middle to right
move 2 from left to middle
move 1 from right to middle
move 1 from middle to left
move 2 from middle to right
move 1 from left to middle
move 1 from middle to right
The Minimum step is 8
Process finished with exit code 0

本文介绍了一个汉诺塔问题的变体,其中盘子不能直接从'左'移动到'右',必须经过'中'。通过递归方法详细阐述了解决方案,包括相邻柱子和不相邻柱子的移动策略,并提供了测试程序及其结果。
1345

被折叠的 条评论
为什么被折叠?



