| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2791 人关注过本帖
标题:汉诺塔问题
只看楼主 加入收藏
习惯被动
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:139
专家分:144
注 册:2012-3-5
结帖率:84.62%
收藏
已结贴  问题点数:20 回复次数:6 
汉诺塔问题
程序代码:
#include<iostream.h>
void move(char one,char anoth)
{
    cout<<one<<"移动到"<<anoth<<endl;
}

void hanoi(int n,char no1,char no2,char no3)
{
    //
    if (n==1) move(no1,no3);
    else
    {
        hanoi(n-1,no1,no3,no2);//
        move(no1,no3);
        hanoi(n-1,no2,no1,no3);//
    }
}

void main()
{
    void hanoi(int n,char no1,char no2,char no3);
    int m;
    cout<<"请输入A柱上的金盘子总数:";
    cin>>m;
    cout<<"当有"<<m<<"个金盘子时,移动步骤依次为:"<<endl;
    hanoi(m,'A','B','C');
}
程序如上能不能解释一下else那部分的递归是怎么回事,本人看了半天看不懂。
搜索更多相关主题的帖子: 不锈钢 
2012-03-10 13:23
yiqiliu1209
Rank: 2
等 级:论坛游民
帖 子:5
专家分:21
注 册:2012-3-10
收藏
得分:0 
hanoi(n-1,no1,no3,no2);//         把no1柱子上的n-1个盘子以no3柱子为中转转到no2柱子
        move(no1,no3);               把no1柱子上的1个盘子移到no3柱子
        hanoi(n-1,no2,no1,no3);//    把no2柱子上的n-1个盘子以no1柱子为中转转到no3柱子

最后由嵌套循环实现了no1上的n个盘子移到了no3柱子

这是我的理解,仅供参考
2012-03-10 14:00
习惯被动
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:139
专家分:144
注 册:2012-3-5
收藏
得分:0 
回复 2楼 yiqiliu1209
n-1个盘一起移动吗?不是每次只能移动一个吗?如果不是一起移动,那计算机是怎么把那n-1个盘按要求移动的,上面的代码好像没有具体的做法。能不能解释详细点?
2012-03-10 19:02
非死亡!
Rank: 8Rank: 8
来 自:四川
等 级:蝙蝠侠
帖 子:179
专家分:760
注 册:2011-10-31
收藏
得分:0 
不像重复回答,不过这样的问题:请看这里:https://bbs.bccn.net/viewthread.php?tid=6664&extra=page%3D1%26amp%3Bfilter%3Ddigest

能力 技巧
2012-03-10 22:41
习惯被动
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:139
专家分:144
注 册:2012-3-5
收藏
得分:0 
回复 4楼 非死亡!
那个帖子我看过,不过就是弄不懂计算机是怎么运行的,我从代码里面看不懂这个算法。能不能给个详细的解释。拜托了。
2012-03-11 00:31
achj198781
Rank: 2
等 级:论坛游民
帖 子:18
专家分:42
注 册:2012-3-9
收藏
得分:20 
这个是那天在网上看到的:x,y,z就是对应A.B.C三根柱子
汉诺塔问题的重点是分析移动的规则,找到规律和边界条件。
若需要将n个盘子从A移动到C就需要(1)将n-1个盘子从A移动到B;(2)将你第n个从A移动到C;(3)将n-1个盘子再从B移动到C,这样就可以完成了。如果n!=1,则需要递归调用函数,将A上的其他盘子按照以上的三步继续移动,直到达到边界条件n=1为止。

思路清楚了,程序就好理解了。程序中的关键是分析好每次调用移动函数时具体的参数和对应的A、B、C塔的对应的关系。下面来以实际的例子对照程序进行说明。
①move(int n,int x,int y,int z)
②{
   if (n==1)
      printf("%c-->%c\n",x,z);
   else
   {
      move(n-1,x,z,y);
      printf("%c-->%c\n",x,z);
      {getchar();}//此句有必要用吗?感觉可以去掉的吧
      move(n-1,y,x,z);
  }
}

比如有4个盘子,现在全部放在A塔上。盘子根据编号为1、2、3、4依次半径曾大。现在要将4个盘子移动到C上,并且是按原顺序罗列。首先我们考虑如何才可以将4号移动到C呢?就要以B为中介,首先将上面的三个移动到B。此步的操作也就是程序中的①开始调入move函数(首次调用记为一),当然现在的n=4,然后判断即③n!=1所以不执行④而是到⑤再次调用move函数(记为二)考虑如何将3个盘移动到B的方法。此处是递归的调用所以又一次回到①开始调入move函数,不过对应的参数发生了变化,因为这次要考虑的不是从A移动4个盘到C,而是要考虑从A如何移动移动3个盘到B。因为n=3,故不可以直接移动要借助C做中介,先考虑将两个移动到C的方法,故再一次到⑤再一次递归调用move函数(记为三)。同理两个盘还是不可以直接从A移动到C所以要以B为中介考虑将1个移动到B的过程。这次是以B为中介,移动到C为目的的。接下来再一次递归调用move函数(记为四),就是移动到B一个,可以直接进行。程序执行③ ④句,程序跳出最内一次的调用(即跳出第四次的调用)返回上一次(第三次),并且从第三次的调用move函数处继续向下进行即⑧,即将2号移动到了C,然后继续向下进行到
⑩,再将已经移到B上的哪一个移回C,这样返回第二次递归(以C为中介将3个盘移动到B的那次)。执行⑧,将第三个盘从A移动到B,然后进入⑩,这次的调用时因为是将C上的两个盘移到B以A为中介,所以还要再一次的递归调用,对应的参数传递要分析清楚,谁是原塔谁是目标塔,谁是中介塔。过程类似于上面的分析,这里不再重复论述了。
2012-03-11 13:40
习惯被动
Rank: 3Rank: 3
等 级:论坛游侠
威 望:1
帖 子:139
专家分:144
注 册:2012-3-5
收藏
得分:0 
回复 6楼 achj198781
谢谢,回答很详细!
2012-03-12 11:35
快速回复:汉诺塔问题
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.048251 second(s), 9 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved