汉诺塔小游戏——函数递归思想

前言

在世界中心贝拿勒斯(在印度北部)的圣庙里,一块黄铜板上插着三根宝石针。印度教主神梵天在创造世界的时候,在其中一根针上从下到上地穿好了由大到小的64片金片,这就是所谓的汉诺塔。不论白天黑夜,总有一个僧侣在按照下面的法则移动这些金片:一次只移动一片,不管在哪根针上,小片必须在大片上面。僧侣们预言,当所有的金片都从梵天穿好的那根针上移到另外一根针上时,世界就将在一声霹雳中消灭,而梵塔、庙宇和众生也都将同归于尽。

这就是古老的印度传说中著名的汉诺塔问题,不管这个传说的可信度有多大,如果考虑一下把64片金片,由一根针上移到另一根针上,并且始终保持上小下大的顺序。这需要多少次移动呢?这里需要递归的方法。假设有n片,移动次数是f(n).显然f(1)=1,f(2)=3,f(3)=7,且f(k+1)=2*f(k)+1。此后不难证明f(n)=2^n-1。n=64时,

假如每秒钟一次,共需多长时间呢?一个平年365天有31536000秒,闰年366天有31622400秒,平均每年31557600秒,计算一下:

18446744073709551615秒

这表明移完这些金片需要5845.42亿年以上,而地球存在不过45亿年,太阳系的预期寿命据说也就是数百亿年。真的过了5845.42亿年,不说太阳系和银河系,至少地球上的一切生命,连同梵塔、庙宇等,都早已经灰飞烟灭。

思考

如果只有两个圆盘,那么我们只需要三步

(图一)

如果是三个盘子的话

(图二)

我们将图一图二对比,

(左)(右)

如果我们先把右边的三个圆盘,看成两个整体,那么它和左图是否有相同之处呢?

函数递归的思想

经过思考我们发现,汉诺塔问题,本质上就是函数递归的思想。

无论有多少个圆盘,我们都可以看成n-1个圆盘和1个圆盘这两个整体,而将两个“整体”起始柱移动到目标柱上,只需要三步。

由此我们得到代码

#include<stdio.h>
 
//        盘子个数   起始柱   辅助柱  目标柱
void hanoi(int n, char qs, char fz, char mb)
{
    if (n==0)
        return;
    else 
    {
        //第一步,把A柱上面的n-1个盘子利用B移动到C
        hanoi(n - 1, A, B, C);

        //第二步,直接输出A柱最底下最大的盘子移到C柱的过程。此时A柱为起始柱,C柱为目标柱
        printf("%s->%s\n", A, C);

        //第三步,把B柱上面的n-1个盘子利用A移动到C
        hanoi(n - 1, B, A, C);
    }
}


int main()
{
    int n = 0;
    printf("请输入在A柱上的盘子的个数:>");
    scanf("%d", &n);
    char A = 'A';
    char B = 'B';
    char C = 'C';
    hanoi(n,A,C,B);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值