目录
前言
Hi~ 你好!
欢迎点击我的博客 : )
这是我的学习总结,希望也能帮助到你
我的博客地址:hi~,我在这里~,欢迎关注哦,
三连不迷路,优质内容持续更新!
一.汉诺塔问题
1.什么是汉诺塔问题
汉诺塔问题,又称河内塔问题,是经典的递归问题。该问题源于印度传说中有一个庙塔,塔内有三个底座,其中一根柱子上面套着64个不同大小的金盘,目标是将这些金盘移到另外一个柱子上。在移动过程中,小盘必须放在大盘的上面,且每次只能移动一个盘子。
2. 算法思路
- 如果只有一个盘子,则直接把盘子从起始位置移动到目标位置;
- 如果有 n (n>1) 个盘子,则先将 n-1 个盘子从起始位置经过目标位置移动到中转位置;
- 接着,将第 n 个盘子从起始位置移动到目标位置;
- 最后,将 n-1 个盘子从中转位置经过起始位置移动到目标位置;
3.递归求解
3.1 解题思路
hanoiMove
方法表示汉诺塔移动的过程,参数n
表示盘子的数量,start
、mid
和end
分别表示起始位置、中转位置和目标位置。当n
等于 1 时,直接将起始位置的盘子移动到目标位置;当n
大于 1 时,先将n-1
个盘子(因为每次只能移动一个,中间包含了一系列过程)从起始位置经过目标位置移动到中转位置,然后将第n
个盘子(同样包含了过程)从起始位置移动到目标位置,最后将n-1
个盘子从中转位置经过起始位置移动到目标位置。在
main
方法中,设置了盘子的数量n
为 3,并指定了起始位置为 'A',中转位置为 'B',目标位置为 'C'。最后调用hanoi
Move方法求解并打印出移动的步骤
其实离谱就离谱在,调用了三次递归,在嵌套的过程中,很容易出错
但大概就是下图的这个情况:不断的递归,n的值在不同的递归下,并不一致
3.2 图解
![](https://img-blog.csdnimg.cn/1f00bca7179d45de92f6f858040e3223.png)
3.3 代码实现
public static void hanoiMove(int n, char start, char mid, char end) {
if (n == 1) {
System.out.println("将一个盘子从"+start + "移动到" + end);
} else {
hanoiMove(n - 1, start, end, mid);
System.out.println("将一个盘子从"+start + "移动到" + end);
hanoiMove(n - 1, mid, start, end);
}
}
4.迭代法
4.1 解题思路
迭代方法通过循环来解决问题
用栈数据结构来模拟迭代方法。将盘子的值和对应的塔放入不同的栈中,然后根据奇偶性来选择移动的顺序。通过循环执行
totalMoves
次移动操作,每次从栈中取出对应的盘子和塔进行移动
4.2 代码实现
public static void hanoiMath(int n, char start, char mid, char end) {
if (n <= 0) {
return;
}
int totalMoves = (int) Math.pow(2, n) - 1;
boolean isEvenNumberOfDisks = (n % 2 == 0);
for (int i = 1; i <= totalMoves; i++) {
if (isEvenNumberOfDisks) {
if (i % 3 == 1) {
System.out.println("从 " + start + " 移动到 " + end);
} else if (i % 3 == 2) {
System.out.println("从 " + start + " 移动到 " + mid);
} else if (i % 3 == 0) {
System.out.println("从 " + mid + " 移动到 " + end);
}
} else {
if (i % 3 == 1) {
System.out.println("从 " + start + " 移动到 " + mid);
} else if (i % 3 == 2) {
System.out.println("从 " + start + " 移动到 " + end);
} else if (i % 3 == 0) {
System.out.println("从 " + mid + " 移动到 " + end);
}
}
}
}
public static void main(String[] args) {
int n = 3; // 设置盘子的数量
hanoiMath(n, 'A', 'B', 'C');
}
5.数学公式法
5.1 解题思路
汉诺塔问题可以通过数学公式来求解,而无需进行实际的盘子移动。根据数学推导,对于n个盘子,在最优解下,总共需要移动2^n-1次。同时,可以得出移动的规律:奇数次移动时,盘子依次从起始塔到目标塔;偶数次移动时,盘子依次从起始塔到中转塔,再从中转塔到目标塔。
5.2 代码实现
public static void hanoiMath2(int n, char start, char mid, char end) {
if (n <= 0) {
return;
}
int totalMoves = (int) Math.pow(2, n) - 1;
boolean isEvenNumberOfDisks = (n % 2 == 0);
for (int i = 1; i <= totalMoves; i++) {
if (isEvenNumberOfDisks) {
if (i % 3 == 1) {
System.out.println("从 " + start + " 移动到 " + end);
} else if (i % 3 == 2) {
System.out.println("从 " + start + " 移动到 " + mid);
} else if (i % 3 == 0) {
System.out.println("从 " + mid + " 移动到 " + end);
}
} else {
if (i % 3 == 1) {
System.out.println("从 " + start + " 移动到 " + mid);
} else if (i % 3 == 2) {
System.out.println("从 " + start + " 移动到 " + end);
} else if (i % 3 == 0) {
System.out.println("从 " + mid + " 移动到 " + end);
}
}
}
}
后记
看到这里,希望能帮到你~
您的点赞 ,收藏 ,关注 是我创作的最大动力!
同时也欢迎在评论区进行交流,共同进步~