博客
关于我
C【入门】(递归专题)
阅读量:345 次
发布时间:2019-03-01

本文共 2850 字,大约阅读时间需要 9 分钟。

最近随着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;}

最后总结发言

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

生命不息 奋斗不止

转载地址:http://dkza.baihongyu.com/

你可能感兴趣的文章
MySQL 快速创建千万级测试数据
查看>>
mysql 快速自增假数据, 新增假数据,mysql自增假数据
查看>>
MySql 手动执行主从备份
查看>>
Mysql 批量修改四种方式效率对比(一)
查看>>
mysql 批量插入
查看>>
Mysql 报错 Field 'id' doesn't have a default value
查看>>
MySQL 报错:Duplicate entry 'xxx' for key 'UNIQ_XXXX'
查看>>
Mysql 拼接多个字段作为查询条件查询方法
查看>>
mysql 排序id_mysql如何按特定id排序
查看>>
Mysql 提示:Communication link failure
查看>>
mysql 插入是否成功_PDO mysql:如何知道插入是否成功
查看>>
Mysql 数据库InnoDB存储引擎中主要组件的刷新清理条件:脏页、RedoLog重做日志、Insert Buffer或ChangeBuffer、Undo Log
查看>>
mysql 数据库中 count(*),count(1),count(列名)区别和效率问题
查看>>
mysql 数据库备份及ibdata1的瘦身
查看>>
MySQL 数据库备份种类以及常用备份工具汇总
查看>>
mysql 数据库存储引擎怎么选择?快来看看性能测试吧
查看>>
MySQL 数据库操作指南:学习如何使用 Python 进行增删改查操作
查看>>
MySQL 数据库的高可用性分析
查看>>
MySQL 数据库设计总结
查看>>
Mysql 数据库重置ID排序
查看>>