使用java递归,展现完整的汉诺塔移动步骤。
目录
1 汉诺塔具体分析
1.1 自顶向下分析汉诺塔
自顶向下思想指将复杂的问题分解为小问题,最后解决所有小问题,即可解决小问题构成的复杂问题
在汉诺塔中,对于n个盘,可以看成1 到 n - 1 的所有盘和最底层的第 n 个盘两个部分,即简化为移动 n - 1 和 n 两个整体。移动这两个整体只需 3 步:
1)先将n - 1 的盘移动到 B 柱
2)将 n 的盘移动到C柱
3)将 n - 1 的盘移动到C柱
1.2 递归和分治
递归即函数自身调用自身的过程。
在汉诺塔问题中具体算法如下:
hanoi(n, A, B, C);
hanoi(n - 1, A, C, B)
move(A ->C);
hanoi(n - 1,B, A, C)
分治是一种算法,将复杂的问题分解为多个没有重叠的子问题,最后这些子问题解决后的到的解就是复杂问题的解。
1.3 切忌跨层分析
谨记分析汉诺塔问题时,只需牢固的掌握两个整体(n - 1 和 n)两个部分的移动情况,分析代码的递归实现是极其复杂的。
1.4 形参和实参
实参指传入函数的实际的值。
形参指函数参数列表中具有一定意义的值。形参会接收实参的值,在函数的运行过程中,是以实参的值进行操作。
编写代码时,形参必须满足一定的规范,提高代码的可阅读性。
1.5 有意义的标识符
在命名形参时,必须满足一定的规范,提高代码的可阅读性。
1.6 时间复杂度分析
在汉诺塔问题中,规定移动第n 个盘子所需要的次数为 f(n) ,对于 n 个盘子来说,移动所有的盘子分为三步,如上述。
即 f(n) = f(n - 1) + 1 + f(n - 1) 且 n = 1 ,f(n) = 1;
通过对递归方程求解(非齐次线性递归方程求解),可以得到 f(n) = 2 ^ n - 1;
1.7 递归栈
栈是一种数据结构。
在执行递归函数时,每调用一次自身函数,会进行一次入栈,当满足递归函数的某一条件后,会从上到小依次出栈,出栈时,会执行完函数所有的语句。
1.8 汉诺塔问题空间复杂度分析
对于汉诺塔问题来说,假设有n 个盘子,在执行函数时,依次会有 n - 1 ,n - 2, n - 3,
n - 4 ... 的函数入栈,当只有 1 个盘子入栈时,开始向下递归。即空间复杂度为 n。
2 具体实现效果
2.1 代码实现
package com.haspedu.test;
public class Hanoi {
public static void main(String[] args) {
HanoiMove hanoiMove = new HanoiMove();
hanoiMove.moveTheStack(3, 'a', 'b', 'c');
}
}
class HanoiMove {
public void moveTheStack(int n, char paraA, char paraB, char paraC) {
if(n == 1) {
System.out.println(paraA + "->" + paraC);
}else {
moveTheStack(n - 1, paraA, paraC, paraB);
System.out.println(paraA + "->" + paraC);
moveTheStack(n - 1, paraB, paraA, paraC);
}
}
}
2.2 代码效果