C【入门】(递归专题)

最近随着C语言的学习,接触到一种特殊的思想---------递归
本章专门又来总结递归的思想已经递归的使用方式,在学习这里是我想到一个特别的东西用来了解递归——————俄罗斯套娃!!! 听我细细道来
在这里插入图片描述就是这个很妖娆的东西帮助我们了解递归。
假如,你面前有一组套娃,现在想知道它们有多少个但是每个娃娃又没有标号,我们应该怎么去数。正常人都是这样数的。我们拿出来一个 个数+1 一直到最后一个娃娃 最后知道总数。
现在我们用递归的思想去数娃娃,假设最外面的娃娃 编号为 n 那么我们要知道有多少个就得打开它 去看n-1 这样n-1 就是最外面的一层,以此类推当我们最终当拿到最里面的娃娃时 反向加和就知道总共有多少娃娃!!
在这里插入图片描述开始数–
1 打开最外面一层
在这里插入图片描述我们发现了里面还有 接着打开了里面的
2 打开第二层
在这里插入图片描述就这样一直一直 做下去 总能全部都打开
N。直到第N步
在这里插入图片描述终于全部打开了 这下就可以从右向左 一个一个加和 就知道有多少娃娃了

综上所述我们可以知道递归的特性

俄罗斯娃娃总有最小的一个 所以递归就得有极限 不能无限递归下去这样没意义
###必须有一个明确的递归结束条件,称为递归出口
但是这样数娃娃 效率实在是惨不忍睹 我们首先得一个一个全部打开又得从最小的再加回来
###递归算法解题通常显得很简洁递归算法解题的运行效率较低
更重要的一点我们实在计算机中 实现 所以计算机在我们每次进行递归返回值时 为这个算法开辟新的栈用看来存储,万一这个循环特别大计算机就会发生栈溢出!!
###在递归调用的过程当中系统为每一层的返回点、局部量等开辟了栈来存储。递归次数过多容易造成栈溢出

科普 栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表

(此处部分内容参考 @花生酱Scarlett 此处声明仅供学习)

套娃套够了 就来套题!!!

斐波那契数列

说递归就必须数兔子 一个斐波那契数列 1 1 2 3 5 8 13 21 34… 一般来讲就是初始两个数都为1 后面的数字 总是这个数字之前的两个数字之和!
f(1) = 1; f(2) = 1; f(3) = f(1) + f(2);以此内推1                                x = 1f(x) =    1       x = 2f(x - 1)  + f(x - 2)        x >= 3
从数学上很好理解

#define _CRT_SECURE_NO_WARNINGS 1
#include "stdio.h"
#include "stdlib.h"
/*
   主要完成 斐波那契数列
   1 1 2 3 5 8 13 21 34.。。
*/

int Factorial_Non(int  n){  
//先使用简单的 不是递归的方法去写 
		/*
主要用代码实现 f3=f1+f2;
	 */
	int f1 = 1;	
	int f2 = 1;
	int f3,i;
	if (n <= 2){
		return  1;
	}
	else{
		for (i = 1; i <= n; i++){    
			f3 = f1 + f2;
			f1 = f2;
			f2 = f3;
		}
	}
	return f3;
}
/*
递归
从最外层想要 f(n) 就得知道 f(n-1)和f(n-2);;
同理 f(n-1)=f(n-2)+f(n-3)...直到 算出 f3=f1+f2
在反向可得 fn
*/
int Factorial(int n){
	if (n <= 2){
		return 1;
	}else{
		return Factorial(n - 1) + Factorial(n-2);
	}
	
}
int main(){
	int n;
	scanf("%d", &n);
	printf("%d", Factorial(n));
	system("pause");
	return 0;
}

总结 递归尤其要理解计算停止的条件 是n<=2

编写一个函数实现n^k,使用递归实现

看到有两个变量不要慌乱 我们来慢慢研究 第一次看不懂 代值进去 一步一步来
例如 计算 2^3
所以计算 2^3 可换为2 * 2^2 将问题改成求 2^2
同理2^2 等于 22
最后可得 2^3=2
2*2;

#define _CRT_SECURE_NO_WARNINGS 1
#include "stdio.h"
#include "stdlib.h"
/*
	使用递归实现 N^K
*/
int power(int n, int k){
	if (n == 1){
		return 1;
	}
	else  if(k == 1){
		return n;
	}
	else{
		return n*power(n, k - 1);
	}
	
}
int main(){
	int n, k;
	scanf("%d %d", &n, &k);
	printf("%d", power(n, k));
	system("pause");
	return 0;
}

总结 这里我引入了两个参数 实际上变化的 只有K一项
在这里插入图片描述

写递归函数DigitSum(n)实现输入一个整数 输出个个数位加和

难点在于输入 多位数怎样去将 每个数位分割加和
在这里插入图片描述

int addition(int n){
	if (n <= 9){
		return n;
	}else{
		return n % 10 + addition(n / 10);
	}
}
int main(){
	int n;
	scanf("%d", &n);
	printf("%d", addition(n));
	system("pause");
	return 0;
}

编写一个函数 reverse_string(char * string)(递归实现)

不能使用C库函数 反方向输出
这里必须 传人参数是一个指针 在C语言中 指针作为参数时就可以当作是一个数组的首地址完全可以理解为一个数组

int Reverse_strring(char *string){
	if (*string == '\0'){
		printf("%c", *string);
	}
	else{
		Reverse_strring(++string);    //此处string 可以当作数组的元素 类比string[1++] 调数组下一个元素作为参数 传入下一个递归 
		printf("%c",*(--string));   //为什么此处是--string ?此处的--string 与之前 ++string有何不同 这里的String 是上面的string++到数组结尾然后再反向--
	}
	return 0;
}
int main(){
	char* string = "asddas ";
	Reverse_strring(string);
	system("pause");
	return 0;
}

最后总结发言

我是这样认为的 递归在解决问题是着重考虑的是一层递归和一层递归的共同性,提取共同性反复迭代,就像俄罗斯套娃 每个娃娃结构相同。
生命不息 奋斗不止

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值