一、斐波那契数列
斐波那契数列十分神奇,在生活中也十分常见,比如说由其可以得到黄金螺旋线,黄金螺旋线可以在鹦鹉螺的外壳上看到,向日葵的种子排列是黄金螺旋线,还有台风与飓风的螺旋也是黄金螺旋线。在数学中,斐波那契数列就是除了该数列的第一、二项都为1以外,其它的任意一项都是其前两项的和,例如:1 1 2 3 5 8 13 21 34 55 89。接下来我们来看看利用VS打印斐波那契我数列的实例:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int fib(int i);
int main()
{
int a;
printf("请输入斐波那契数列的最后一项的项数:");
scanf("%d", &a);
for (int i = 1; i <=a; i++)
{
printf("fib(%d)=%d\n", i, fib(i));
}
return 0;
}
int fib(int i)
{
if (i == 1 || i == 2)
{
return 1;
}
else if (i > 2)
{
return fib(i - 1) + fib(i - 2);
}
}
这样写虽然能够实现打印a项斐波那契数列的功能,但是如果项数a过大的话会花费大量的时间来进行重复的计算,效率十分的低下,大家可以试试。
二、计算阶乘
阶乘就不用介绍了吧!直奔主题:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
int count(int i);
int main()
{
int num;
printf("请输入一个需要计算其阶乘的数:");
scanf("%d", &num);
printf("结果为%d", count(num));
return 0;
}
int count(int i)
{
if (i == 0 || i == 1)
{
return 1;
}
else
{
return i * count(i - 1);
}
}
阶乘的定义为n!=n*(n-1)*(n-2)*(n-3)......2*1,通过函数的递归,我们可以知道count(i-1)=(i-1)*count(i-2),如此循环递归就可以计算出n的阶乘。
三、汉诺塔问题
汉诺塔(Hanoi Tower),又称河内塔,是一种经典的数学问题和递归算法示例。这个问题最初是由法国数学家爱德华·卢卡斯(Édouard Lucas)在1883年提出的,而“汉诺塔”这个名称则是来源于越南河内的一个传说。
汉诺塔的问题描述如下:有三根柱子,标记为A、B和C,A柱上穿有若干个不同大小的圆盘,最上面的圆盘最小,依次往下递增。初始状态下,所有圆盘都按照大小从小到大的顺序堆叠在A柱上。目标是将所有圆盘移动到C柱上,并保持原有的大小顺序,同时遵守以下规则:
- 一次只能移动一个圆盘。
- 移动过程中,任何时刻大圆盘都不能放在小圆盘的上面。
这个问题的经典解法是使用递归算法。基本思路是将问题划分为三个子问题:将n-1个圆盘从A移动到B,将最大的圆盘从A移动到C,最后将n-1个圆盘从B移动到C。这一过程可以递归地应用于子问题,直到圆盘数量为1时,可以直接移动。递归的结束条件是当只有一个圆盘时,直接将它从起始柱移动到目标柱。
汉诺塔问题不仅是一个有趣的数学谜题,而且它还展示了递归算法在解决问题时的简洁性和高效性。这个问题也经常被用作计算机科学和算法设计的教学案例。下面来看看如何用程序来解决汉诺塔问题:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
//汉诺塔问题的递归解法
//num表示盘子的数量
//source表示原来的柱子
//middle表示中间的柱子
//target表示目标柱子
void hanno(int num,char source,char middle,char target);
int main()
{
int num;
printf("请输入盘子的个数:");
scanf("%d", &num);
hanno(num,'A','B','C');
return 0;
}
void hanno(int num, char source, char middle, char target)//通过函数的递归关系来解决汉诺塔问题
{
if (num == 1)
{
printf("移动%c上的盘子到%c上\n", source, target);
return;//递归基:最终会递归到这里然后再结束
}
hanno(num - 1, source, target, middle);//将n-1个盘子从原来的柱子移动到中间的柱子
printf("移动%c上的盘子到%c上\n", source, target);//将剩余的一个盘子从原来的柱子移动到目标柱子
hanno(num - 1, middle, source, target);//将n-1个盘子从中间的柱子移动到目标柱子
}
四、总结
通过以上的例子,大家对函数的递归有了一个较为模糊的印象,ChatGPT这样定义它——
递归(Recursion)是指在解决问题的过程中,通过调用自己来解决问题的一种编程或数学技术。在计算机科学中,递归是通过将问题分解为更小、相似的子问题,并通过对这些子问题的解决来解决原始问题的方法。我的理解是在子函数中调用它本身,然后通过将复杂问题分解为相似的简单问题来解决。