梵天命令一个叫婆罗门的门徒将所有的圆盘移动到另一个柱子上(一共有三根柱子),移动过程中必须遵守以下规则:
- 每次只能移动柱子最顶端的一个圆盘;
- 每个柱子上,小圆盘永远要位于大圆盘之上;
问,将n个圆盘移动到另一个柱子上一共需要移动多少次?
先考虑简单情况:
①只有一个盘:直接从原始柱移动到目标柱子上,只需要一步,因此hanoi(1)=1;
②有两个盘:
- 将盘2从原始柱A移动到辅助柱B上;
- 将盘1从原始柱A移动到目标柱C上;
- 将盘2从辅助柱B移动到目标柱C上;
因此hanoi(2)=3;
③有三个盘:
- 将盘3从A移动到C;
- 将盘2从A移动到B;
- 将盘3从C移动到B;
- 将盘1从A移动到C;
- 将盘3从B移动到A;
- 将盘2从B移动到C;
- 将盘3从A移动到C;
因此hanoi(3)=7;
不难从上面的流程图发现,当n=3时,我们需要先将上面的两个较小的圆盘移动到圆柱B上,然后将最大的圆柱移到目标住C上;然后是将B上较小的圆盘移动到A上,再将B上最大的圆盘移动到C上;最后将最小的圆盘从A移到C上。
我们称移动过程为hanoi(),移动过程需要直到圆盘数、原始柱子、辅助柱子、目标柱子,因此我们定义:
hanoi(n,source,auxiliary,target)
现在,我们需要将n个圆盘从source柱上移动到target柱上,完成三步:
- 将n-1个较小的圆盘从source移动到auxiliary上:hanoi(n-1,source,target,auxiliary);
- 将最大的圆盘从source移动到target上:1;
- 将n-1个圆盘从auxiliary移动到target上:hanoi(n-1,auxiliary,source,target)
一共移动:hanoi(n-1,source,target,auxiliary)+1+hanoi(n-1,auxiliary,source,target)
Hanoi塔问题的解决过程就是不断将问题分解成小问题解决的过程,先分后治,和归并排序思想一样。
完整代码:
package day14;
public class Hanoi {
/**
*
*********************
* @Title: hanoi
* @Description: TODO(Move a number of plates)
*
* @param paraNumber The number of plates
* @param paraSource The source pole.
* @param paraAuxiliary The auxiliary pole.
* @param paraTarget The target pole.
* @return The number of moving.
*********************
*
*/
public static int hanoi(Integer paraNumber, char paraSource, char paraAuxiliary, char paraTarget) {
if (paraNumber == 1) {
System.out.println(paraSource + "->" + paraTarget + " ");
return 1;
} // Of if
int sourceToAuxiliary = hanoi(paraNumber - 1, paraSource, paraTarget, paraAuxiliary);
System.out.println(paraSource + "->" + paraTarget + " ");
int auxiliaryToTarget = hanoi(paraNumber - 1, paraAuxiliary, paraSource, paraTarget);
return sourceToAuxiliary + 1 + auxiliaryToTarget;
}
/**
*
*********************
* @Title: main
* @Description: TODO(The entrance of the program)
*
* @param args Not used now.
*********************
*
*/
public static void main(String args[]) {
int tempNumber = hanoi(3, 'A', 'B', 'C');
System.out.println("The number of moving is: " + tempNumber);
}// Of main
}// Of class Hanoi