汉诺塔递归问题

给定三根柱子,记为A,B,C ,其中 A 柱子上有 n 个盘子,从上到下编号为 0到N-1,且上面的盘子一定比下面的盘子小。问:将 A 柱上的盘子经由 B柱移动到 C 柱最少需要多少次?

从A移动到C,注意大的不能放在小的上面,所以我们要借助另一个柱子解释B柱子实现移动

但是要使最大的柱子放在C上面肯定要把上面的小盘子放在B柱,此时C柱为工具柱,辅助A上面n-1个盘子移动到B

所以,汉诺塔问题其实可以分解成两个小问题

将比最大的盘子小n-1个盘子的从A移动到B柱上

再第n个盘子从A移动到C

再将B柱n-1个盘子移动到C柱子

为什么我写了三个,却只说有两个问题呢,因为第三步骤完全就是第一步和第二部的重复;

仔细想想做第二步骤,肯定要经历第一步,第一步是什么,将n-1个移动到B,对吧

它不就是一个小型的汉诺塔问题吗,只是目标柱子从C柱子变成了B柱子,把A上面的移动到B对吧

那如果是n-1个就可以再分解成一个个小汉诺塔问题,只是目标柱在不断替换

举个例子

三层汉诺塔

盘子名字分别为123,柱子是ABC

进行第一步将12移动到B

12移动到B也是一个小型汉诺塔问题,第一步是将1移动到C

然后进行小型问题的第二步把2移动到B

是不是相当于完成了前两步,然后在吧1移动到B

经过这个小汉诺塔问题,相当于完成了大型汉诺塔问题的第一步就是把12移动到B

然后把3移动到c

之后又是一个小汉诺塔问题,此时进行到大汉诺塔第三步,将12移动到c

12移动到c不就和12从a移动到b差不多的步骤,只是工具柱的改变

上面不就是吧3层的汉诺塔问题拆解成两个2层汉诺塔

然后两个2层汉诺塔分解成两个一层汉诺塔吗。

就是一个分解的过程

代码如下


 

#include <stdio.h>

void hanoi(int n,char,char,char);

int main()

{
    

    int n;

    printf("输入汉诺塔层数:");

    scanf("%d",&n);

    printf("\n");

    hanoi(n,'A','B','C');

    return 0;

}

void hanoi(int n,char x,char y,char z)

{
    

    if(n==1)

    printf("%c to %c\n",x,z);//一层汉诺塔问题直接移动

    else

    {
        hanoi(n-1,x,z,y);//把汉诺塔问题分解,这是第一个n-1层的汉诺塔问题,目标柱是B

        printf("%c to %c\n",x,z);//这个相当于非一层汉诺塔问题的第二步骤,把最大的移动到z

        hanoi(n-1,y,x,z);/*这是第二个n-1层汉诺塔问题,这不就相当于3层汉诺塔分解成两个2层汉诺塔问题

由于递归属性,他们内部还会再分最后化成2的n-1次方个一层汉诺塔问题,目标柱是c,原柱为b,工具柱是a。*/

    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小袁拒绝摆烂

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

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

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

打赏作者

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

抵扣说明:

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

余额充值