汉诺塔问题看不懂,有人能帮一下我吗?看不懂那个过程,或者告诉我怎么去想这个问题。

这个题目的核心是递归吧,所以希望听完你的讲解后,我能了解到一点。

想要把方块从A柱子移到C柱子,需要B柱子作为媒介,比如说,一个方块可以直接放到C上,但是两个方块就不行了,要先把小的那块放在B柱子上,然后将第二块方块从A柱子移到C柱子上,再将第一块方块移到C柱子上,从2块方块开始,以后有n块方块,就必须要将n-1块方块放在B柱子上,第n块方块移到C上,再将n-1块方块移到C上。而对于n-1块方块,又有n-2块方块需要移到A或者C上,这样第n-1块方块才能移到B上。核心公式就是f(n)=2^n-1次
码字不易,不知帮到您了没有追问

公式我也知道,但是我想知道书上那代码的过程。。是怎么体现递归的。
重点在递归不是这些公式啦。抱歉啦。

追答

是具体的过程还是结果代码?我附上结果代码,你看一下吧。

#include
#include
#include
using namespace std;
int ans=1;
void fun(int num)
{
if(num==0)
return;
ans*=2;
fun(num-1);
}

int main()
{
int n;
cin>>n;
fun(n);
cout<<ans-1<<endl;
system("pause");
return 0;
}
从第n个柱子到第n-1个柱子,所需要的移动数要*2,当我们不需要移动时,返回即可,比如说,当我们移动一个柱子,那就是2-1次,当我们要移动2个柱子时,就是2*2-1次

如果说是递归的话,是在已知规律的条件下对于问题的一种推导,我们知道汉诺塔问题的公式是f(n)=2^n-1,那么我们定义了ans,每次询问这个问题前面问题的结果是什么,最后*2就可以了,边界是num=0,这个边界我也是现推的,不同的代码有不同的边界条件,我发现输入1的时候输出0,所以把边界改成了num=0,这样当你询问f(1)的时候,它就会查询f(0),发现到边界,返回。ans*2=2,2-1=1

再提一下,递归使用的是一种名字叫做"栈"的东西,系统中的栈基本在10万左右,超出了系统的栈就会栈溢出,许多时候我们都是自己定义栈的。关于栈的知识你要上网自学,我这就不讲模拟栈的代码了

温馨提示:内容为网友见解,仅供参考
第1个回答  2016-08-04
#include <stdio.h>

#include <iostream>

using namespace std;

//入参int n:代表第n个盘子

int move(int n,char a, char b)
{
printf("==>==>: 把第 %d 个盘子 从 %c座 搬到 %c座\n\n",n,a,b);
return 0;
}

//入参int n:代表 共剩余n个盘子
int hanoi(int n,char a,char b,char c)
{
cout<<"******************int hanoi(int n,char a,char b,char c) begin!!!"<<endl;
if (n == 1)
{
cout<<"剩余盘子数 n="<<n<<",盘子在"<<a<<"座上,可以直接搬到"<<c<<"座"<<endl;
}
else
{
cout<<"剩余盘子数 n="<<n<<",盘子在"<<a<<"座上,需借助"<<b<<"座,搬到"<<c<<"座"<<endl;
}
if( n==1 )
{
cout<<endl<<"11111=>: ";
move (1,a,c);
}
else
{
hanoi(n-1,a,c,b);//根据上面解说知道:移动n个盘子需要(2的n次方)-1步,这里需要移动n-1个盘子需要(2的n次方)-2步,也就是说这里的第一轮递归 要进行 n-1 层递归循环,才会结束调用,完成 将 n-1 个盘子从a座上借助c座,最终放到了b座上,
move(n,a,c);//完成 将 最后一个盘子即第 n 个盘子从a座上放到了c座上,至此完成第一轮的调用,其结果是将最后一个盘子完成了任务,其余的盘子都还在b座上放着呢,下面一步是对剩余的n-1个盘子进行新一轮的递归调用
hanoi(n-1,b,a,c);//开启新一轮的递归调用
};
if (n == 1)
{
cout<<"对应-----------剩余盘子数 n="<<n<<",盘子在"<<a<<"座上,可以直接搬到"<<c<<"座"<<endl;
}
else
{
cout<<"对应-----------剩余盘子数 n="<<n<<",盘子在"<<a<<"座上,需借助"<<b<<"座,搬到"<<c<<"座"<<endl;
}
cout<<"int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@"<<endl<<endl;
return 0;
}
int main()
{
freopen("hanoi.in","r",stdin);
freopen("hanoiOutPut.txt","w",stdout);
int num;
scanf("%d",&num);
cout<<"开始"<<endl<<endl;
hanoi(num,'A','B','C');
cout<<endl<<endl<<"结束"<<endl<<endl;
return 0;
}

/*开始

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=3,盘子在A座上,需借助B座,搬到C座

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=2,盘子在A座上,需借助C座,搬到B座

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=1,盘子在A座上,可以直接搬到C座

11111=>: ==>==>: 把第 1 个盘子 从 A座 搬到 C座

对应-----------剩余盘子数 n=1,盘子在A座上,可以直接搬到C座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

==>==>: 把第 2 个盘子 从 A座 搬到 B座

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=1,盘子在C座上,可以直接搬到B座

11111=>: ==>==>: 把第 1 个盘子 从 C座 搬到 B座

对应-----------剩余盘子数 n=1,盘子在C座上,可以直接搬到B座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

对应-----------剩余盘子数 n=2,盘子在A座上,需借助C座,搬到B座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

==>==>: 把第 3 个盘子 从 A座 搬到 C座

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=2,盘子在B座上,需借助A座,搬到C座

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=1,盘子在B座上,可以直接搬到A座

11111=>: ==>==>: 把第 1 个盘子 从 B座 搬到 A座

对应-----------剩余盘子数 n=1,盘子在B座上,可以直接搬到A座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

==>==>: 把第 2 个盘子 从 B座 搬到 C座

******************int hanoi(int n,char a,char b,char c) begin!!!

剩余盘子数 n=1,盘子在A座上,可以直接搬到C座

11111=>: ==>==>: 把第 1 个盘子 从 A座 搬到 C座

对应-----------剩余盘子数 n=1,盘子在A座上,可以直接搬到C座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

对应-----------剩余盘子数 n=2,盘子在B座上,需借助A座,搬到C座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

对应-----------剩余盘子数 n=3,盘子在A座上,需借助B座,搬到C座

int hanoi(int n,char a,char b,char c) end end end end end end @@@!!!@@@

结束*/追问

你这样的话和我看教材一样..没多少帮助。那你可以告诉我递归是怎么一回事吗?

第2个回答  2016-08-05
我在校那时也不明白,后来想,等以后用到的时候在学吧.
后来工作之后发现,我竟然从没用过递归.
有的时候是运行环境不支持,单片机类的跑起来容易爆栈,或者编译器直接就报错.
更多的时候是在搞软件工程,算法反而用的不多.
如何调用库,或者自己写一个库,快速完成需求.
如何写一个良好的界面.
如何写出层次清晰,功能完善的代码.
如何写出后期维护起来更容易的代码.
以上这些事情反而成为了我工作中的主要内容.

我并没有答题,关于递归我也自认肯定没有其它几位答主答的更好.
我只是在讲,题主如果现在不理解,也不必强求.编程还有很多更好玩的东西.追问

那样太迟了...我现在想看看能不能从别人的理解中知道点什么。

第3个回答  2016-08-04
假如有A,B,C三根杆,一开始全部圈在A杆,目的用汉诺塔规则借助C杆将所有圈从A转移到C。
一个圈(1):1(A->B)1次
两个圈(1、2):1(A->C)(1次),2(A->B),1(A->C),共3次
三个圈(1、2、3):1、2(A->C)(3次),3(A->B),1、2(A->C)(3次),共7次
..................
以此类推,假设n代表圈圈个数,z为总次数,则有:
z(n)=z(n-1)+1+z(n-1)=2*z(n-1)+1
z(3)=z(2)+1+z(2)=2*3+1=7
递归:z(3)=2*z(2)+1=2*(2*z(1)+1)+1=7追问

次数的话是2^n-1吧??而且- -!我没讲明来意。。。

第4个回答  2016-08-07
赵薇演过一个电影叫《天地英雄》,我是看了那部电影,然后明白了递归的含义。

汉诺塔的程序把我弄迷糊了!高人指点一下!
如果看不懂的话,先去搞懂递归的手法比较好~~~hanoi(n-1,one,three,two); \/*这里明白是怎么回事*\/ 我相信你如果真正明白了这句,就能明白全文了。先从m为3的情况解释吧:(下面为方便,简写运行过程)hanoi(3,A,B,C)->if (n==1) move(A,C);\/\/不满足 ->hanoi(2,A,C,B);->->if...

解释下汉诺塔问题
pascal 我不懂,但是可以给你讲一下问题的逻辑。hanoi 的原型是这样的:将n个盘子借助B从A移到C,不能出现大小颠倒。(相信你知道这些,简单罗嗦两句)那么分析如下:采用倒推法,要实现目的,只要能将上面的n-1个盘子从A移到B,就可以了(后续步骤是将第n个盘子移到C,再将B上的n-1个移到C...

求汉诺塔的C语言算法步骤,当M=3时,程序是怎么算的,实在看不懂哪步到...
汉诺塔问题的C语言递归算法主要分为三个步骤,当M=3时,具体实现如下。首先,调用h(3),即解决3个圆盘问题。在这个步骤中,需要调用h(2),解决两个圆盘问题。接着,执行m()操作,进行移动。之后,再次调用h(2),解决两个圆盘问题。在这个过程里,每一个h(2)调用又会进一步调用h(1)解决单个圆盘...

求真正理解汉诺塔问题的编程大神回答一下,当n=3时,用c语言编写的汉诺塔...
一开始我接触汉诺塔也是很不解,随着代码量的积累,现在很容易就看懂了,因此楼主主要还是对递归函数的理解不够深刻,建议你多写一些递归程序,熟练了自己就能理解。圆盘逻辑移动过程+程序递归过程分析 Hanoi塔问题, 算法分析如下,设A上有n个盘子,为了便于理解我将n个盘子从上到下编号1-n,标记为盘子1...

各位C语言高手,请问你对“汉诺塔问题”了解几成呢?好难啊!!!
简单移动一下即可。简而言之就是,每次把除最后底下的一个移开,然后将最低一下的一个移到最后一根柱子上去。这样说的确是很抽象,不容易理解的,强烈建议你在纸上画图来模拟一下这个过程。就是根据你这个程序来画,这样会方便很多~~我最初的时候试过,理解起来真的很有帮助。

汉诺塔该怎么玩,方法
汉诺塔算法介绍:一位美国学者发现的特别简单的方法:只要轮流用两次如下方法就可以了。把三根柱子按顺序排成“品”字型,把所有圆盘按从大到小的顺序放于柱子A上,根据圆盘数量来确定柱子排放的顺序:n若为偶数的话,顺时针方向依次摆放为:ABC;而n若为奇数的话,就按顺时针方向依次摆放为:ACB。

汉诺塔问题公式是什么?
汉诺塔 汉诺塔(又称河内塔)问题是印度的一个古老的传说。开天辟地的神勃拉玛在一个庙里留下了三根金刚石的棒,第一根上面套着64个圆的金片,最大的一个在底下,其余一个比一个小,依次叠上去,庙里的众僧不倦地把它们一个个地从这根棒搬到另一根棒上,规定可利用中间的一根棒作为帮助,但每次...

汉诺塔5层怎么走
具体来说,我们可以将5层的汉诺塔问题看作是由多个小问题组成的:首先移动上面的4个盘子到辅助柱子上,然后将最大的盘子移动到目标柱子上,最后再将那4个盘子从辅助柱子移动到目标柱子上。而移动4个盘子到辅助柱子的过程,又可以看作是一个4层的汉诺塔问题,同样可以递归地解决。在实际操作中,我们可以...

汉诺塔1到9最快分别是几次? 可以告诉我计算方法吗?
1层:1次 2层:3次 3层:7次 4层:15次 5层:31次 6层:63次 7层:127次 8层:255次 9层:511次 计算公式:f(x)=2^x-1

汉诺塔函数递归调用问题给个解释
一个函数可以直接或间接地调用自已,这就叫做“递归调用”。C,C++语言不允许在函数的内部定义一个子函数,即它无法从函数的结构上实现嵌套,而递归调用的实际上是一种嵌套调用的过程,所以C,C++并不是实现递归调用的最好语言。但只要我们合理运用,C,C++还是很容易实现递归调用这一语言特性。 先看一个最直接的递归...

相似回答