【C++练习系列】汉诺塔问题(你悟了吗?)

1.例题

题目:用递归解决汉诺塔问题(把n个盘子从A柱子移到C柱子,每次只能移动一个盘子,在任何时候,任何柱子上的盘子都是大盘在上,小盘在下)。

2.详细解析

(1)动画直观感受一下

【B站:悟道小番薯】汉诺塔问题动画

(2)描述

你看到了吗?
动画中有六块盘子,我们将三根柱子从左到右分为A,B,C,从上到下的盘子分为:1到6

解决问题的思路是这样子的:

,先看最下面的一块盘子,它想的是
(1)只要在它上面的盘子先从A移到B,
(2)它在从A移到C,
(3)最后那五块盘子再从B移到C,那就完成任务了吗!

于是,它下了两条命令(从动画中可以证明:命令是可以被执行的):
第一条:1到5的盘子从A移到B
第二条:1到5的盘子从B移到C
最小面板子的想法
,再看第二块盘子的想法:(这里插一句话:6块盘子从A移到C,和5块盘子从A移到B,5块盘子从B移到C的要求是不是差不多,只是少了一块盘子而已)
要完成第一块盘子交给的(第一个)任务:
(1)只要在它上面的盘子先从A移到C,
(2)它在从A移到B,
(3)最后那四块盘子再从C移到B,那就完成任务一(1到5的盘子从A移到B)了吗!在这里插入图片描述
要完成第一块盘子交给的(第二个)任务:
(1)只要在它上面的盘子先从B移到A,
(2)它在从B移到C,
(3)最后那四块盘子再从A移到C,那就完成任务二(1到5的盘子从B移到C)了吗!


你发现了吗?最下面的盘子和第5个盘子的任务是差不多一样的:

除了第一块盘子,所有的盘子都想先让在它上的盘子移到另外的柱子上,自己再移到目标柱子,最后让其他柱子回到目标柱子上。

这就是的思想:要完成6个盘子从A移到C,你先把前5个盘子的任务做好;
要想把前5个盘子的任务做好,你先把前4个盘子的任务做好;
要想把前4个盘子的任务做好,你先把前3个盘子的任务做好;


你先把第1个盘子的任务做好。

这是的思想:你把第1个盘子移好了,我就能把前两个盘子移好;
这样我就能把前三个盘子移好;


我就能把6个盘子移好。

(3)代码

一.分块解析

这是将盘子移动的函数

void move(char X, char Y)
{
    cout << X << " ——> " << Y << endl;
}

这就是汉诺塔的函数了,一个函数中调用自身的函数叫做递归函数,else里面是递的思想,if里面是归的思想,hanoi函数能实现把n个盘子从A柱子移到C柱子上。

hanoi(n - 1, A, C, B):这句话不简单,它的意思是第n-1块盘子要完成的第一个任务:把n-1个盘子从A盘移到B盘。
它调用的也是hanoi函数,它把A装进char A这个桶子里,把C装进char B这个桶子里,把B装进char C这个桶子里,当它实现move(A,C)这个语句时是把第n-1块盘子从A柱子移到B柱子上的,同理,其他也是一样的(不要被它的外表所迷惑!)。

void hanoi(int n, char A, char B, char C)//这相当于桶子
{
    if (n == 0)
        return;
    else
    {
        hanoi(n - 1, A, C, B); //这就是任务一,把在目前的盘子上面的盘子移到其他柱子上
        move(A, C);            //将目前的盘子移到目标柱子上
        hanoi(n - 1, B, A, C); //最后将其他盘子移到目标柱子上
    }
}

这是主函数

int main()
{
    int n;
    cout << "请输入A柱子上的盘子数目:";
    cin >> n;

    hanoi(n, 'A', 'B', 'C');//调用hanoi函数

    return 0;
}

二.完整代码

#include <iostream>
using namespace std;
void move(char X, char Y)
{
    cout << X << " ——> " << Y << endl;
}
void hanoi(int n, char A, char B, char C)
{
    if (n == 0)
        return;
    else
    {
        hanoi(n - 1, A, C, B); 
        move(A, C);            
        hanoi(n - 1, B, A, C); 
    }
}
int main()
{
    int n;
    cout << "请输入A针上的盘子数目:";
    cin >> n;
    hanoi(n, 'A', 'B', 'C');
    return 0;
}

最后我想说的是,这是我的【C++练习系列】的第四篇文章,喜欢的话希望可以点一下赞,并关注我的前面三篇文章,ok,再见啦。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

在下_诸葛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值