汉诺塔和青蛙跳台阶(递归函数的应用)

汉诺塔和青蛙跳台阶(递归函数的应用)

1. 汉诺塔

  • 从数学角度来看

如下图所示,从左到右有A、B、C三根柱子,其中A柱子上面有从小叠到大的n个圆盘,现要求将A柱子上的圆盘移到C柱子上去,期间只有一个原则:一次只能移到一个盘子且大盘子不能在小盘子上面,求移动的步骤和移动的次数
这里写图片描述
(1)n == 1

         第1次  1号盘  A---->C       sum = 1 次

(2) n == 2

         第1次  1号盘  A---->B

         第2次  2号盘  A---->C

         第3次  1号盘  B---->C        sum = 3 次

(3)n == 3

        第1次 1号盘 A—->C

        第2次 2号盘 A—->B

        第3次 1号盘 C—->B

        第4次 3号盘 A—->C

        第5次 1号盘 B—->A

        第6次 2号盘 B—->C

        第7次 1号盘 A—->C sum = 7 次

不难发现规律:1个圆盘的次数 2的1次方减1

       2个圆盘的次数 2的2次方减1

         3个圆盘的次数 2的3次方减1

         。  。   。    。   。 

        n个圆盘的次数 2的n次方减1

故:移动次数为:2^n - 1

  • 算法:

    实现这个算法可以简单分为三个步骤:

        (1) 把n-1个盘子由A 移到 B;

        (2) 把第n个盘子由 A移到 C;

        (3) 把n-1个盘子由B 移到 C

  • 代码如下

#include <stdio.h>
#include <math.h>
void Heneita(int n, char a, char b, char c)
{
    int num = 0;
    if (n==1)
    {
        printf("%c-->%c\n", a, c);
    }
    else
    {
        Heneita(n - 1, a, c, b);
        Heneita(1, a, b, c);
        Heneita(n - 1, b, a, c);
    }
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    Heneita(n,'A','B','C');
    printf("%d\n", (int)pow(2, n) - 1);
    return 0;
}
  • 运行结果:
    这里写图片描述
    2.青蛙跳台阶
    问题1:一只青蛙一次可以跳上1个台阶,也可以跳上2个台阶。求青蛙跳上n级台阶总共有多少种跳法?
    分析:这个问题从前往后分析太过复杂,不妨换个思路,如果青蛙想跳上第n个台阶,就只有两种跳法:从第n-1个台阶跳上来或者从第n-2个台阶跳上来。这样我们就可以先算第n个台阶的跳法然后用递归往下推算。第n个台阶:f(n)=f(n-1)+f(n-2);第一个台阶:f(n)=1;第二个台阶:f(n)=2;发现这个其实是斐波那契数列,如此就简单了。
    规律如下图:
    这里写图片描述

  • 代码如下:

#include <stdio.h>
int jump(int n)
{
    if (n <= 0)
    {
        printf("输入错误\n");
        return 0;
    }
    else if (n == 1 || n == 2)
    {
        return 1;
    }
    else if (n > 2)
    {
        return jump(n - 1) + jump(n - 2);
    }
}
int main()
{
    int n = 0;
    int ret = 0;
    scanf("%d", &n);
    ret = jump(n);
    printf("%d\n", ret);
    return 0;
}
  • 运行结果:
    这里写图片描述

    问题2:每次可以跳1–n个台阶,跳上n个台阶有多少中跳法;
    分析:同样从后往前分析,跳上第n个台阶有n-1中可能。从第一个台阶直接跳上第n个台阶……………….从第n-1个台阶跳上第n个台阶,一共有:
    f(n)=f(n-1)+f(n-2)+f(n-3)+………f(1);
    f(n-1)=f(n-2)+f(n-3)+………..f(1);
    …………………………………………
    …………………………………………..
    f(n)=2f(n-1)=4f(n-2)=8f(n-3)=………..=(2^(n-1))f(1);
    f(n)=2f(n-1);
    f(1)=1;

  • 代码如下:
#include <stdio.h>
#include <math.h>
int jump(int n)
{
        if (n <= 0)
        {
            printf("输入错误\n");
            return 0;
        }
        else
        {
            return pow(2, n-1);
        }
}
int main()
{
    int n = 0;
    int ret = 0;
    scanf("%d", &n);
    ret=jump(n);
    printf("%d\n", ret);
    return 0;
}
#include <stdio.h>
int jump(int n)
{
    if (n <=0)
    {
        printf("输入错误\n");
        return 0;
    }
    if (n==1)
    {
        return 1;
    }
    else
    {
        return 2*jump(n-1);
    }
}
int main()
{
    int n = 0;
    int ret = 0;
    scanf("%d", &n);
    ret = jump(n);
    printf("%d\n", ret);
    return 0;
}
  • 运行结果:

这里写图片描述

猜你喜欢

转载自blog.csdn.net/yulong__li/article/details/81317993