C语言递归篇章

本文详细介绍了递归的概念,递归的简单和复杂实例(如阶乘、斐波那契数列和二进制转换),以及递归的条件、运行逻辑和可能遇到的问题,包括栈溢出和优化尾递归。同时探讨了递归与迭代的区别,以及如何避免递归导致的内存消耗问题。
摘要由CSDN通过智能技术生成

递归的讲解系统分析

什么是递归

本质上就是一种算法

最简单递归

栈溢出 没有限制条件 导致无穷尽的调用自己 从而溢出 最后变成死递归

 

____________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________________

分析阶乘

无符号整形 这里不考虑溢出的情况 数值过大需要考虑溢出的情况

__________________________________________________________________________________________________________________________________________________________

递归的详解

蓝色是推:推出去 红色是归:回归

__________________________________________________________________________________________________________________________________________________________

递归具备条件以及运行逻辑

递归详解图片

代码 

#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

意思就是 这里是打印每次递归的数值

但是如果是%的话 就是打印每次递归数值后的取模

数值的%

意思就是

  • 35
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值