c++汉诺塔问题求解
voidhanoi(intn,charone,chartwo,charthree){voidmove(charx,chary);if(n==1){move(one,thr...
void hanoi(int n,char one,char two,char three)
{
void move(char x,char y);
if (n == 1)
{
move(one,three);
}
else
{
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
}
}
void move(char x, char y)
{
cout<<x<<"-->"<<y<<endl;
}
这个难理解 。比如一共有4个盘,求大神把代码的执行过程讲解 展开
{
void move(char x,char y);
if (n == 1)
{
move(one,three);
}
else
{
hanoi(n-1,one,three,two);
move(one,three);
hanoi(n-1,two,one,three);
}
}
void move(char x, char y)
{
cout<<x<<"-->"<<y<<endl;
}
这个难理解 。比如一共有4个盘,求大神把代码的执行过程讲解 展开
4个回答
展开全部
这是一个典型的递归算法,也是数学中经典的的问题。
其实算法非常简单,当盘子的个数为4时,移动的次数应等于2^4 – 1=15次。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:按顺时针方向依次摆放 A B C;(这里我用ABC代替你代码中的one two three 为了看着方面)
⑴按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
⑵接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
⑶反复进行⑴⑵操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动片:
4阶汉诺塔移动:A→B,A→C,B→C,A→B,C→A,C→B,A→B,A→C,(最大的已经移动到C,A上没有盘片)
然后是B→C,B→A,C→A,B→C(此时第二大盘片已经挪到C上,B上没有盘片)
然后A→B,A→C(此时第三大盘片已经挪到C)
最后B→C 结束
当你理解了这个过程再去看算法 其实就是一层一层往里调用hanoi函数,中间用move移动盘子,然后再一层一层返回。
不知道说到这你能不能想明白,如果还不明白可追问
其实算法非常简单,当盘子的个数为4时,移动的次数应等于2^4 – 1=15次。首先把三根柱子按顺序排成品字型,把所有的圆盘按从大到小的顺序放在柱子A上,根据圆盘的数量确定柱子的排放顺序:按顺时针方向依次摆放 A B C;(这里我用ABC代替你代码中的one two three 为了看着方面)
⑴按顺时针方向把圆盘1从现在的柱子移动到下一根柱子,若圆盘1在柱子A,则把它移动到B;若圆盘1在柱子B,则把它移动到C;若圆盘1在柱子C,则把它移动到A。
⑵接着,把另外两根柱子上可以移动的圆盘移动到新的柱子上。即把非空柱子上的圆盘移动到空柱子上,当两根柱子都非空时,移动较小的圆盘。这一步没有明确规定移动哪个圆盘,你可能以为会有多种可能性,其实不然,可实施的行动是唯一的。
⑶反复进行⑴⑵操作,最后就能按规定完成汉诺塔的移动。
所以结果非常简单,就是按照移动规则向一个方向移动片:
4阶汉诺塔移动:A→B,A→C,B→C,A→B,C→A,C→B,A→B,A→C,(最大的已经移动到C,A上没有盘片)
然后是B→C,B→A,C→A,B→C(此时第二大盘片已经挪到C上,B上没有盘片)
然后A→B,A→C(此时第三大盘片已经挪到C)
最后B→C 结束
当你理解了这个过程再去看算法 其实就是一层一层往里调用hanoi函数,中间用move移动盘子,然后再一层一层返回。
不知道说到这你能不能想明白,如果还不明白可追问
更多追问追答
追问
我就是疑惑 hanoi(n-1,one,three,two);这个为什么可以表示把n-1圆盘借助C柱移到B柱
追答
递归就是代码简介,但理解困难。不是一句两句能和你解释清楚的,hanoi(n-1,one,three,two)又调用了hanoi(n-1,one,three,two),然后再调用,每次调用n都会减1,直到n=1 满足if (n == 1)
{
move(one,three);
}
即A-->C
然后再一层层返回,返回时执行hanoi(n-1,two,one,three);
这其实是一个函数调用另一个函数,只不过这里调用的是自己。
这是另一个递归,注意参数,不再是one two three 而是two,one,three
这会使two赋值给one,one赋值给two,three赋值给three
即one和two发生交换,
第一次返回时n=2,第二次累加。
move(one,three);
相当于move(two,three)
实现了圆盘借助C柱移到B柱
你可以假设n=2,自己模拟走一下,然后=3,再走一遍。类似于进程中断保护现场那个图。
你有没有谭浩东的那本《C程序设计》第三版
翻到174页有很详细的解释
不懂你就继续追问,这个确实不好理解,何况你都没学过数据结构
展开全部
汉诺塔问题怎么解决,可以利用递归法来解决。设移动盘子数为n,为了将这n个盘子从A杆移动到C杆,可以以C盘为中介,从A杆将1至n-1号盘移至B杆。将A杆中剩下的第n号盘移至C杆。以A杆为中介;从B杆将1至n-1号盘移至C杆。这样汉诺塔问题就解决了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
关于递归的理解,首先你要认定你的函数能够执行你想要的操作。比如,定义hanoi的时候,你就要认为它就是把n个盘,从one经过two移动到three。怎么移动n个盘呢?先把n-1个移动到中间那个柱子two,就是hanoi(n-1,one,three,two);然后把剩下的一个从one移到three,最后把那n-1个移动到three
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
执行过程就是:把n-1圆盘借助C柱移到B柱,第n个圆盘直接移到C柱(目的柱),反复如此。。。
如果你学过数据结构的二叉树的话,那么对汉诺塔的移动整个过程可以说是了如指掌。因为很明显它就是一个棵完全二叉树的中序遍历的结果。
如果没有学过数据结构的二叉树,顶多就是知道汉诺塔的游戏规则。 目前它的注释也是从宏观的角度去解释它的每句话的含义。
如果你学过数据结构的二叉树的话,那么对汉诺塔的移动整个过程可以说是了如指掌。因为很明显它就是一个棵完全二叉树的中序遍历的结果。
如果没有学过数据结构的二叉树,顶多就是知道汉诺塔的游戏规则。 目前它的注释也是从宏观的角度去解释它的每句话的含义。
追问
额 数据结构还没学 现在我只是疑惑 把n-1圆盘借助C柱移到B柱用hanoi(n-1,one,three,two);这个表示,为什么实参换了位置就可以了
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询