c++ 汉诺塔问题 递归解决

问题源:

最近在学C++,遇到一个汉诺塔问题,同学都说看不懂,特地解析一下。

问题描述:

注意:一次最多移动一个盘子!
问题原型

解决方案:## 标题

怎么去思考这个问题呢?我们先试着从少到多自己一个一个试试,体验一下过程。

  1. (当n = 1)这个时候很简单,A ------> C 这样就够了。

  2. (当n = 2)这个时候也很简单,A ------> B A------>C B------->C 这样就够了。好像还看不到什么东西 ?_?

  3. (当n = 3)这个时候不那么简单了,{A ------> C A------>B C------->B } {A ------> C} {B------>A B------->C A------->C}
    A---->C
    A---->B
    C---->B

    A---->C

    B---->A
    B---->C
    A---->C
    我们先来看,前三步本质上做了什么:前三步最后的结果其实是把原本在A上的外面两层放到了B上。
    然后是第四步,把A上最底下,也就是第三层放到了C上。
    最后三步的效果其实就是把B上边的两层移到了C上边

整个过程思路是什么?
如果是三层,我先把最外两层从A移到B上,剩下一层从A移到C上,最后,把在B上最外两层又移到C上就可以了。
把最外两层从A移到B,和从B移到C本质上没有区别,只是A字母换成B,B字母又换成C而已。

这时候有同学就很迷惑了,那我怎么把最外面两层从A放到B上呢?其实在前面,我们是不是完成了n = 2的操作,也就是我们可以成功把2个盘子移到C上,所以我们就会发现,我可以把最外边两个从A盘子移到C上,其实也就是说可以把最外边两个从A盘子移到B上,这个过程不过是换了个字母,结合前面进一步说,也就是可以把最外边两个盘子从B盘子移到C上。

这个时候来看看,当n = 2,也就是说A上只有两个盘子的时候我们是怎么做的,A------>B A------->C B------->C
其实也是三步:先把最外一层A----->B;然后最底下一层A------C;最后从B再移到C后;
这里边的A------>B, 和B------->C 过程操作方法是一致的,我们都把它看成n = 1时,A------->C,

问题就很简化了,你应该知道n = n,也就是有n个盘子该怎么办了,如果你的想法和我下面一样,相信你已经理解了,如果不一样,没关系,看看下面代码后再回头看看问题相信你会理解的:
一共就三步:
第一步:把n - 1个A上的外层盘子移到B
第二步:把1个A上的最底下盘子移到C
第三步:把B上的n - 1个盘子移到C上,完成
关于 n -1 个盘子怎么移动,我们又单独分析,它就可以分成
第一步:把(n - 1)- 1个A上的外层盘子移到B
第二步:把1个A上的最底下盘子移到C
第三步:把B上的(n - 1)- 1个盘子移到C上,完成
关于(n - 1)- 1 个盘子怎么移动,我们又单独分析,它就可以分成

最后它会变成2个盘子,2个盘子又可以转成1个盘子,
所以我们只要知道一个盘子怎么做就可以知道n个盘子怎么做了,这也就是递归的妙处。

代码块:

#include <iostream>
using namespace std;

void move(char a,char b)
{
    cout << a << "---->" << b <<endl;
}

void hanoi(int n, char A, char B, char C)
{
    if (n == 1)
    {
        move(A, C);
    }
    else
    {
        hanoi(n - 1, A, C, B);
        move(A, C);
        hanoi(n - 1, B, A, C);
    }
}

int main(int argc, char const *argv[])
{
    int n;
    cout << "请输入层数:";
    cin >> n;
    cout << "移动" << n << "个盘子过程为:" << endl;
    hanoi(n, 'A', 'B', 'C');
    return 0;
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值