汉诺塔问题的理解与疑问以及开头逻辑写出来

it2023-01-08  67

2020.10.20 今天第一次见到汉诺塔问题 理解了一些部分

先将汉诺塔问题大概是什么说一下: 据说创世纪时Benares有一塔波罗教塔,是由三支钻石棒所支撑,开始时神在第一根棒上放置64个由上至下依次由小到大的金盘,并命令僧侣将所有的金盘从第一根石棒移至第三根石棒,且搬运过程中遵守大盘子在小盘子之下的原则,若每日仅搬一个盘子,则当盘子全数搬运完毕之时,此塔将摧毁,也就是世界末日来临之时。

1.一开始将汉诺塔问题看成了数学问题,其实是一个逻辑问题,输出并不是算术而是逻辑。这个想法一开始就误导着我,定义字符是为了算什么呢,一直看不懂定义函数的作用,感觉只是写了个框架,并没有把里面真正的算法写出来,一直陷入这个死循环里,直到看到大佬们的讲解,才从误区走出来。

2.递归的想法也和正常想法不一样,正常人是要看到顺序的逻辑,有前才有后,而递归刚好相反,你先写出后面,这时你要当作前面的已经写好了,以此往回递归,可能是第一次接触这种,还在c语言的循环结构里不能自拔。。。

//n表示需要移动盘子的数量,X表示源塔,Y表示借用塔,Z表示目标塔 //①借助Z塔,将前n-1个盘子从X塔移动到Y塔 Hanoi(n - 1, X, Z, Y); //②将X塔上剩下的1个盘子移到Z塔 printf("\t将第%d个盘片从%c移动到%c\n",n,X,Z); //③借助X塔,将前n-1个盘子从Y塔移动到Z塔 Hanoi(n - 1, Y, X, Z);

这里是自己还有的一些问题,为什么写成这样,就能把(前n-1个盘子从X塔移动到Y塔),(前n-1个盘子从Y塔移动到Z塔),这是为什么,我能理解将n-1个盘子看成整体,但是不懂为什么这么写就能移动。还是说这还是逻辑,实际上计算机里面并没有移动,还是什么其他。

这边放出编写好的汉诺塔问题

#include <iostream> using namespace std; void Hanoi(int n, char X, char Y, char Z) { //n表示需要移动盘子的数量,X表示源塔,Y表示借用塔,Z表示目标塔 if (n == 1) //只有一个盘子时,将其从X塔移动到Z塔 printf("\t将第%d个盘片从%c移动到%c\n", n, X, Z); else { //①借助Z塔,将前n-1个盘子从X塔移动到Y塔 Hanoi(n - 1, X, Z, Y); //②将X塔上剩下的1个盘子移到Z塔 printf("\t将第%d个盘片从%c移动到%c\n",n,X,Z); //③借助X塔,将前n-1个盘子从Y塔移动到Z塔 Hanoi(n - 1, Y, X, Z); } } int main() { Hanoi(3, 'A', 'B', 'C'); return 0; }

我努力将上面的逻辑顺序解释一下

当n=1

Hanoi(1, X, Y, Z); { printf("\t将第%d个盘片从%c移动到%c\n",n,X,Z); }

于是

满足if(n==1) Hanoi(1, X, Y, Z); 所以 X=A,Y=B,Z=C printf("\t将第%d个盘片从%c移动到%c\n", n, X, Z); 即 第一片从A移动到C

当n=2

Hanoi(2, X, Y, Z) { Hanoi(1, X, Z, Y); printf("\t将第%d个盘片从%c移动到%c\n",n,X,Z); Hanoi(1, Y, X, Z); }

将上面的 Hanoi(1, X, Y, Z)代入即可

Hanoi(1, X, Z, Y); 也是就当n=1的时候 X=A,Z=B,Y=C 所以 printf("\t将第%d个盘片从%c移动到%c\n", n, X, Z);

即 第一片从A移动到B

接着运行原先 Hanoi(2, X, Y, Z)中的语句 printf("\t将第%d个盘片从%c移动到%c\n",n,X,Z); n=2,X=A,Y=B,Z=C 所以

将第二片从A移动到C(这里上式是X,Z,Y;所以所以当X=X,Z=Y)

Hanoi(1, Y, X, Z) n=1,Y=A,X=B,Z=C 所以 printf("\t将第%d个盘片从%c移动到%c\n", n, X, Z); 即**第一片从B移动到C**

当n=3,就更为复杂了,按照上面的想法其实大概就能理清楚

最新回复(0)