递归的讲解系统分析
什么是递归
本质上就是一种算法
最简单递归
栈溢出 没有限制条件 导致无穷尽的调用自己 从而溢出 最后变成死递归
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
分析阶乘
无符号整形 这里不考虑溢出的情况 数值过大需要考虑溢出的情况
__________________________________________________________________________________________________________________________________________________________
递归的详解
蓝色是推:推出去 红色是归:回归
__________________________________________________________________________________________________________________________________________________________
递归具备条件以及运行逻辑
递归详解图片
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Factorial(int n)
{
if (n > 0)
{
return n * Factorial(n - 1);
}
}
int main()
{
int i = 0; int sum = 0;
scanf("%d", &i);
int ret = Factorial(i);
printf("%d", ret);
return 0;
}
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
分析顺序打印数字 递归详解
简化
画图详解
保留一份n=121
每一次都保留n的数值
画图推演
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void Fibonacci(int n)
{
if (n > 9)
{
Fibonacci(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
int i = 0;
scanf("%d", &i);
Fibonacci(i);
return 0;
}
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
函数栈再次讲解
传参就开始开辟空间
第二次Printf申请空间
反复运行 每次调用就申请一次空间
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
递归限制条件
最后 是还给操作系统 但是 每次函数栈的销毁是 由寄存器吧数值给带回去
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
简单的说就是 递归的使用不是所有都适合的 使用递归来解决就会产生内存空间的消耗
不使用递归的话 就可以使用迭代的方法
循环是迭代的一种
阶乘
递归的不恰当书写导致的后果
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
分析斐波那契数列
其实不是适合递归求解 因为数值过大的时候 是有问题的
迭代的方式实现 abc之间的相互迭代和转换
返回值 是c
尾递归 尾部的递归 可以用来拿来优化
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
int i = 0; int a = 1; int b = 1; int c = 1;
scanf("%d", &i);
while (i >= 3)
{
c = a + b;
//b = c;
a = b;//这里之所以是先a=b再b=c的原因是 数值是从左到右进行增加的
b = c;
i--;
}
printf("%d", c);
return 0;
}
//在斐波那契数列中,
// 前两个数通常是0和1,然后每个后续的数都是前两个数的和。
// 但是在你的代码中,a、b和c都被初始化为1,这意味着你的代码实际上是从第三个斐波那契数开始的计算,
// 即F(3) = 1,F(4) = 1,F(5) = 2。
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
递归的实际操作和运用
递归的越界问题1
函数的递归经典问题剖析(为什么越界会导致无限循环)+vs调试教程+关于越界问题的解释和函数栈联系-CSDN博客
__________________________________________________________________________________________________________________________________________________________
递归的计算详解
__________________________________________________________________________________________________________________________________________________________
递归实现次幂详解
递归的条件某种意义上结束条件也是起始条件
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<math.h>
int CIMI(int n,int k)
{
if (k == 0)
{
return 1;
}
else
{
return n * CIMI(n, k - 1);
}
}
int main()
{
int n = 0; int k = 0;
scanf("%d", &n);
scanf("%d", &k);
int sum = CIMI(n, k);
printf("%d", sum);
return;
}
//组合函数返回值是1
//在这个函数中,如果k等于0,
// 返回的是1而不是0的原因是因为这个函数实现的是计算组合数的功能。
// 组合数C(n, k)表示从n个元素中选取k个元素的组合数。当k等于0时,表示不选取任何元素,
// 这种情况下只有一种可能,即空集,所以返回的是1。如果返回0的话,就表示没有任何组合,
// 这是不符合组合数的定义的。
//
//所以,如果你想要计算组合数的话,应该保持if(k == 0) { return 1; }这样的写法。12
__________________________________________________________________________________________________________________________________________________________
递归计算每一位的和详解
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int Sumi(int n)
{
if (n == 0)
{
return 0;
}
return (n % 10) + Sumi(n / 10);
}
int main()
{
int i = 0; int sum = 0;
scanf("%d", &i);
int ret = Sumi(i);
//printf("%d", ret);
return 0;
}
/如果您将 Sumi 函数中的基准情况改为 return 1;
// ,那么对于任何非零整数 n,递归将始终返回 1,因为每次递归调用都会加上 1(由于基准情况),
// 而实际上并没有计算除了最低位以外的其他位数字。
//简单说就是 如果==0 返回值是0 如果return 1 等于0的时候返回值是1 0是正常返回
//return 1表示递归调用的返回值为1。
//在递归调用过程中,每次递归都会返回一个值,
// 这些返回的值会被累加起来,最终得到最终的结果。
// 因此,当整数为0时,递归结束,返回的值为0;而当整数不为0时,
// 递归调用的返回值会被累加,最终返回的值比递归结束时的返回值多1。
__________________________________________________________________________________________________________________________________________________________
递归非递归实现阶乘问题详解
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
unsigned int a = 15;
while (a)
{
printf("%d", a % 2);
a = a / 2;
}
return 0;
}
unsigned int无符号整形 可以计算负数
__________________________________________________________________________________________________________________________________________________________
递归方式实现打印一个整数的每一位详解
推出去
回来
代码
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
void Fibonacci(int n)
{
if (n > 9)
{
Fibonacci(n / 10);
}
printf("%d ", n % 10);
}
int main()
{
int i = 0;
scanf("%d", &i);
Fibonacci(i);
return 0;
}
____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________
二进制递归
错误解释 但是递归的逻辑是对的
十进制数 15 的二进制表示从左到右是 1111。
decimalToBinary(15) // 初始调用
= decimalToBinary(7) // 15除以2得到商7余1
= decimalToBinary(3) // 7除以2得到商3余1
= decimalToBinary(1) // 3除以2得到商1余1
= 1 // 1除以2得到商0余1,这是最后一次递归调用,打印最低位1
所以,打印顺序应该是 1, 1, 1, 1, 从最高位到最低位。
举例 如果是打印 n/2
意思就是 这里是打印每次递归的数值
但是如果是%的话 就是打印每次递归数值后的取模
数值的%
意思就是