今天来和大家一起学习递归
这里写目录标题
递归
1.1概念
递归其实是一种解决问题的方法,在C语⾔中,
递归就是函数自己调用自己。
1.2递归的思想
把⼀个大型复杂问题层层转化为⼀个与原问题相似,
但规模较小的子问题来求解;
直到子问题不能再被拆分,递归就结束了。
所以递归的思考方式就是把大事化小的过程。
递归中的递就是递推的意思,归就是回归的意思,接下来慢慢来体会。
1.3递归的限制条件
- 递归存在限制条件,当满足这个限制条件的时候,递归便不再继续。
- 每次递归调用之后越来越接近这个限制条件。
练习
1.计算n的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
代码1(递归)
#include<stdio.h>
int Fact(int n)
{
if (n == 0)
return 1;
else
return n*Fact(n-1);
}
int main()
{
printf("请输入要求的数字\n");
int n = 0;
scanf("%d", &n);
Fact(n);
int ret = Fact(n);
printf("%d\n", ret);
return;
}
运行结果
代码2
#include<stdio.h>
int main()
{
int n = 0;//(求n的阶乘)
printf("请输入n\n");
scanf("%d", &n);
int i = 0;
int sum = 0;
sum = n;//存放阶乘
int a = 0;
a = n;
for (i = 1; i < a; i++)
{
sum *= (n - 1);
n = n - 1;
}
printf("%d\n", sum);
return 0;
}
运行结果
2.输入一个整数m,按照顺序打印整数的每一位。
代码
#include<stdio.h>
void Print(int n)
{
if (n > 9)
{
Print(n / 10);
}
printf("%d ", n%10);
}
int main()
{
printf("请输入要打印的数字\n");
int m = 0;
scanf("%d", &m);
Print(m);
printf("\n");
return 0;
}
运行结果
3.求第n个斐波那契数
递归和非递归分别实现求第n个斐波那契数
1.递归代码
#include<stdio.h>
int Fib(int n)
{
if (n < 2)
{
return n;
}
else
{
return Fib(n - 1) + Fib(n - 2);
}
}
int main()
{
printf("请输入要求的是第几个斐波那契数\n");
int n = 0;
scanf("%d", &n);
int ret;
ret = Fib(n);
printf("第%d个斐波那契数是%d\n",n, ret);
return 0;
}
运行结果
2.非递归代码
#include<stdio.h>
int Fib(int n)
{
int a = 0;
int b = 1;
int c = 0;
int tmp = 0;
while (n >= 2)
{
c = a + b;
a = b;
b = c;
n--;
}
return c;
}
int main()
{
printf("请输入要求的是第几个斐波那契数\n");
int n = 0;
scanf("%d", &n);
int ret;
if (n <= 2)
{
ret = 1;
}
else
{
ret = Fib(n);
}
printf("第%d个斐波那契数是%d\n", n, ret);
return 0;
}
运行结果
4.青蛙跳台阶问题
一只青蛙一次可以跳一级台阶或两级台阶,问每级台阶有几种跳法
代码
#include<stdio.h>
//观察可知,每级台阶的跳法为前两级台阶的跳法之和
int Jump(int n)
{
int ret;
if (n <= 2 )
{
ret = n;
}
else
{
ret = Jump(n - 1) + Jump(n - 2);
}
return ret;
}
int main()
{
printf("请输入青蛙要跳几级台阶\n");
int n;
scanf("%d", &n);
int ret;
ret = Jump(n);
printf("青蛙跳%d台级阶有%d种跳法\n",n,ret);
return 0;
}
运行结果
5. 汉诺塔问题
汉诺塔问题:即在一个装置上有A,B,C三根杆。
在A杆自下而上、由大到小按顺序放置n个圆盘,
我们需要保存原有顺序把A杆上的圆盘全部移到C杆上。
操作过程中,每次只能移动一个圆盘,
并且在移动过程中三根杆上都始终保持大盘在下,小盘在上,
操作过程中盘子可以置于A、B、C任一杆上。
1.求次数
#include<stdio.h>
int hanoi_num(int n)
{
if (n > 1)
{
return 2 * hanoi_num(n - 1) + 1;
}
else
{
return 1;
}
}
int main()
{
int n;
scanf("%d", &n);
printf("次数为:%d", hanoi_num(n));
return 0;
}
2.求步骤
#include<stdio.h>
void hanoi_move(int n, char A, char B, char C)
//参数A,B,C分别为所在杆,中间杆,目标杆
{
if (n > 1)
{
//传入的参数为当前情况下的所在杆,中间杆,目标杆
hanoi_move(n - 1, A, C, B);
printf("%c -> %c\n", A, C);
hanoi_move(n - 1, B, A, C);
}
else
{
printf("%c -> %c\n", A, C);
}
}
int main()
{
int n;
scanf("%d", &n);
hanoi_move(n, 'A', 'B', 'C');
return 0;
}
6.递归实现n的k次方
编写一个函数实现n的k次方,使用递归实现。
代码
#include<stdio.h>
int Pow(int n, int k )
{
if (k == 0)
{
return 1;
}
else
{
return n * Pow(n,k - 1);
}
}
int main()
{
printf("请输入要求什么数的几次方\n");
int n;
scanf("%d", &n);
int k;
scanf("%d", &k);
int ret;
ret = Pow(n, k);
printf("计算结果为:%d\n",ret);
return 0;
运行图片
7.计算一个数的每位之和(递归实现)
写一个递归函数DigitSum(n),输入一个非负整数,
返回组成它的数字之和
例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19
输入:1729,输出:19
代码
#include<stdio.h>
int DigitSum(int n)
{
if (n <= 9)
{
return n;
}
else
{
return DigitSum(n / 10) + DigitSum(n % 10);
}
}
int main()
{
printf("请输入要计算的数字\n");
int n;
scanf("%d", &n);
int ret;
ret = DigitSum(n);
printf("值为%d\n", ret);
return 0;
}
运行图片
总结
递归主要要清楚限制条件及找到规律,然后写出函数;
有时候可能递归会出现一些问题例如栈溢出等问题,这时候要我们使用迭代解决问题。
对递归的分享就到这里了,如果感觉不错,希望可以给博主点个赞或者关注,感谢大家的支持,成为我继续分享的动力,还有什么问题和建议可以在评论区评论,拜拜。