目录
1. 斐波那契数列
2. 汉诺塔
2.1 问题描述
2.2 递归求解
2.3 递归程序设计
3. 青蛙跳台阶
斐波那契数列(Fibonacci sequence)指的是这样一个数列:
1,1,2,3,5,8,13,21,34,55,89...
从第3项开始,每一项都等于前两项之和。
递归算法在计算时存在着大量的重复计算,执行效率低,n值稍大时非常耗费时间。
#include
int fib(int n)
{
if (n <= 2)
return 1;
else
return fib(n - 1) + fib(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fib(n);
printf("%d\n", ret);
return 0;
}
斐波那契数列用迭代算法更高效。
#include
int fib(int n)
{
int a = 1;
int b = 1;
int c = 0;
while (n >= 3)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = fib(n);
printf("%d\n", ret);
return 0;
}
汉诺塔(Tower of Hanoi),又称河内塔,是一个源于印度古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘。
有三根柱子x、y、z,x柱上有n个盘子,每次移动一个盘子,小的只能叠在大的上面,要求将所有盘子从x柱经y柱全部移到z柱上。
将上面n-1个盘子从x柱经z柱全部移到y柱上,再将第n个盘子从x柱移到z柱上,然后将n-1个盘子从y柱经x柱全部移到z柱上。
程序hanoi(n,x,y,z)表示将n个盘子从x柱经y柱全部移到z柱上。
这个问题可以划分成两个自相似的问题,和一次移动:
递归出口:当n=1时,执行move(x,z)。
#include
int count = 0;
//显示盘子的移动轨迹
void move(char ch1, char ch2)
{
count++;
printf("step%d:%c->%c\n",count, ch1, ch2);
}
//将n个盘子从x柱经y柱全部移到z柱上
void hanoi(int n, char x, char y, char z)
{
if (n == 1)
move(x, z);
else
{
hanoi(n - 1, x, z, y);
move(x, z);
hanoi(n - 1, y, x, z);
}
}
int main()
{
int n = 0;
scanf("%d", &n);
hanoi(n, 'a', 'b', 'c');
return 0;
}
输入4
输出:
step1: a->b
step2: a->c
step3: b->c
step4: a->b
step5: c->a
step6: c->b
step7: a->b
step8: a->c
step9: b->c
step10: b->a
step11: c->a
step12: b->c
step13: a->b
step14: a->c
step15: b->c
一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
设函数jump(n)表示青蛙跳上n级台阶的跳法种数。
当n=1时,只有1种跳法。
当n=2时,可以一次跳1级台阶,跳两次;也可以一次跳2级台阶,跳一次。所以一共有2种跳法。
当n>3时,如果先跳1级台阶,还剩n-1级台阶,有jump(n-1)种跳法;如果先跳2级台阶,还剩n-2级台阶,有jump(n-2)种跳法。所以一共有jump(n-1)+jump(n-2)种跳法。
#include
int jump(int n)
{
if (n <= 2)
return n;
else
return jump(n - 1) + jump(n - 2);
}
int main()
{
int n = 0;
scanf("%d", &n);
int ret = jump(n);
printf("%d\n", ret);
return 0;
}
可以看出青蛙跳台阶就是斐波那契数列的应用。