递归和非递归

2023-11-03

1、递归就是函数调用函数本身,运行起来就是函数嵌套函数,层层嵌套,所以函数调用、参数堆栈都是不小的开销,但是程序简单。
2、非递归就是不断地对参数入栈、出栈,省去了函数层层展开、层层调用的开销。虽然参数出入栈次数多了,但是一般都开辟固定的足够大的内存来一次性开辟、重复使用。
3、非递归是从堆栈的角度来编写程序,速度快,但代码复杂。
递归是从问题本身的逻辑角度来编写,虽然速度相对慢,但代码容易理解。

对于同一个问题,如果对速度要求不高,建议用递归方式。

  • 递归和非递归分别实现求第n个斐波那契数。
  • 递归和非递归分别实现strlen
  • 递归和非递归分别实现求n的阶乘
  • 递归实现n^k
  • 递归方式实现打印一个整数的每一位
  • 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和(例如,调用DigitSum(1729),则应该返回1+7+2+9,它的和是19 )
  • 编写一个函数 reverse_string(char * string)(递归实现)
    实现:将参数字符串中的字符反向排列。
    要求:不能使用C函数库中的字符串操作函数。

1.递归和非递归分别实现求第n个斐波那契数
首先对于斐波那契数序列:1 1 2 3 5 8 13 21 34… 从第三项开始,每一项都等于前两项之和。

int count = 0;   //计数计算多少次f1
int Fabonaci(int n)  //递归
{
	if (n == 1 || n == 2)
	{
		count++;   //count计数,体会递归的耗时
		return 1;
	}
	else
	{
		return Fabonaci(n - 1) + Fabonaci(n - 2);  //第n个数的斐波那契等于前两个之和 问题不断化小
	}
}

int main()
{
	printf("%d\n", Fabonaci(5));
	printf("计算%d次f1\n",count);
	system("pause");
	return 0;
}
int Fabonaci(int n) //非递归
{
	int f1 = 1;
	int f2 = 1;
	int f3 = 0;
	int i = 0;
	for (i = 3; i <= n; i++)
	{
		f3 = f2 + f1;  //1(f1) 1(f2) 2(f3)  3  5
		f1 = f2;  
		f2 = f3;       //1(f1) 2(f2)  3 (f3)  5
	}
	return f3;
}

int main()
{
	printf("%d\n", Fabonaci(10));
	system("pause");
	return 0;
}

2.递归和非递归分别实现strlen
strlen遇到\0停止,引用数组引进头文件<string.h> ,字符串的长度就是字符个数。

#include<assert.h>
int count = 0;
int MyStrlen1(char *str)  //非递归
{
	//int count = 0;
	assert(str != NULL);  //断言str传进来不为空
	while (*str != '\0')
	{
		count++;
		str++;
	}
	return count;
}

int main()
{
	char str[] = "abcdef";
	
	printf("%s\n", str);
	MyStrlen1(str);

	printf("%d\n", count);
	system("pause");
	return 0;
}
int MyStrlen(char *str)  //递归
{
	if (*str == '\0')
	{
		return 0;
	}
	else
	{
		return 1 + MyStrlen(str + 1);
	}
}

int main()
{
	char  str[] = "abcdef";// *str = "abcdef";
	int len = MyStrlen(str);
	printf("%d\n", len);
	system("pause");
	return 0;
}

3.递归和非递归分别实现求n的阶乘

int Fac(int n)//5! = 5*4!   5*4*3!
{
	if (n == 1)
	{
		return 1;
	}
	else
	{
		return n*Fac(n - 1);
	}
}
int main()
{
	printf("%d", Fac(5));
	system("pause");
	return 0;
}

4.递归实现n^k

int MyPow(int n, int k)  //递归
{
	if (k == 0)
	{
		return 1;
	}
	else
	{
		return n*MyPow(n, k - 1);   //n*n^k-1 = n^k
	}
}

int main()
{

	int res = MyPow(5,3);
	printf("%d\n",res);

	system("pause");
	return 0;
}

5.递归方式实现打印一个整数的每一位

void print(int n)   //123   
{
	if (n > 9)
	{
		print(n / 10);
	}
	printf("%d ", n % 10);
}

int main()
{
	print(123);
	system("pause");
	return 0;
}

6 写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和

 int DigitSum(int n)
{
	if (n < 10)
	{
		return n;
	}
	else//14   123
	{
		return DigitSum(n / 10) + n % 10;
	}
}

int main()
{
	int res = DigitSum(1729);
	printf("%d\n",res);
	system("pause");
	return 0;
}

递归的过程是***先递后归*** 1729 172 17 1为递过程 ; 1 7 2 9为归过程

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

void reverse_string(char *p) //递归
{
	int len = strlen(p);     //不包括\0
	char tmp = *p;
	*p = *(p + len - 1);   
	*(p + len - 1) = '\0';    //保证字符串长度不变
	if (strlen(p + 1) > 1)
	{
		reverse_string(p + 1);
	}
	*(p + len - 1) = tmp;    // *p 和 *(p+len-1) 进行交换
}

int main()
{
	char str[] = "abcdef";
	printf("%s\n", str);
	reverse_string(str);
	printf("%s\n", str);
	system("pause");
	return 0;
}
void reverse_string(char *str) //非递归
{
	char *left = str;
	char *right = str + strlen(str) - 1;
	while (left < right)
	{
		char tmp = *left;
		*left = *right;
		*right = tmp;   //交换
		left++;
		right--;
	}
}
int main()
{
	char str[] = "abcdef";
	printf("%s\n", str);
	reverse_string(str);
	printf("%s\n", str);
	system("pause");
	return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

递归和非递归 的相关文章

  • PAT 5 猴子吃桃问题(递归)

    猴子吃桃问题 15 分 一只猴子第一天摘下若干个桃子 当即吃了一半 还不过瘾 又多吃了一个 第二天早上又将剩下的桃子吃掉一半 又多吃了一个 以后每天早上都吃了前一天剩下的一半加一个 到第N天早上想再吃时 见只剩下一个桃子了 问 第一天共摘了
  • 栈系列之 递归实现一个栈的逆序

    算法专题导航页面 算法专题 栈 栈系列之 栈排序 栈系列之 最小栈的实现 栈系列之 用栈实现队列 栈系列之 递归实现一个栈的逆序 题目 使用递归来完成一个栈的逆序操作 其他限制 不能借助任何其他数据结构 图示 无 分析 递归思想原本就和栈这
  • 树的遍历(bfs+递归)

    题目描述 一个二叉树 树中每个节点的权值互不相同 现在给出它的后序遍历和中序遍历 请你输出它的层序遍历 输入描述 第一行包含整数 N 表示二叉树的节点数 第二行包含 N 个整数 表示二叉树的后序遍历 第三行包含 N个整数 表示二叉树的中序遍
  • 《C和指针》笔记27:递归

    递归所需要的两个特性 存在限制条件 当符合这个条件时递归便不再继续 每次递归调用之后越来越接近这个限制条件 这里没有用计算阶乘和菲波那契数列的例子说明递归 作者指出前者递归并没有提供任何优越之处 而后者效率之低是非常恐怖的 下面程序的目的是
  • 关于二叉树的几种遍历方法

    转载请注明出处 http blog csdn net pony maggie article details 38390513 作者 小马 一 二叉树的一些概念 二叉树就是每个结点最多有两个子树的树形存储结构 先上图 方便后面分析 1 满二
  • 排序算法(4)----快速排序

    快速排序由C A R Hoare在1962年提出 它的基本思想是 通过一趟排序将要排序的数据分割成独立的两部分 其中一部分的所有数据都比另外一部分的所有数据都要小 然后再按此方法对这两部分数据分别进行快速排序 整个排序过程可以递归进行 以此
  • 用斐波那契数列理解记忆化搜索

    记忆化搜索有点类似于dfs dp 但是初学算法 对于记忆化搜索的机制以及什么时候应该使用记忆化搜索还比较迷茫 所以这篇博客以斐波那契数列的求法为例 用C 实现记忆化搜索 对斐波那契数列的递归求解进行优化 1 斐波那契数列 1 1 问题定义
  • 递归和非递归

    1 递归就是函数调用函数本身 运行起来就是函数嵌套函数 层层嵌套 所以函数调用 参数堆栈都是不小的开销 但是程序简单 2 非递归就是不断地对参数入栈 出栈 省去了函数层层展开 层层调用的开销 虽然参数出入栈次数多了 但是一般都开辟固定的足够
  • 递归及递归的简单运用之4种方法解斐波那契数列

    什么是递归 若一个对象部分的包含自己或用它自己给自己定义 那么我们说这个对象是递归的 若一个过程直接或间接的调用自己 那么这个过程是递归的 递归的思想是把问题分解为规模更小具有与原问题相同解法的子问题 因此可以让我们思考的方式更加简单 程序
  • 算法竞赛进阶指南 递归实现组合型枚举

    文章目录 1 递归实现指数型枚举 2 递归实现排列型枚举 题目链接 https ac nowcoder com acm contest 998 B 1 递归实现指数型枚举 思路 在 递归实现指数型枚举 的基础上 如果已经选择了超过 m m
  • C++递归算法之2的幂次方表示

    2的幂次方表示 任何一个正整数都可以用2的幂次方表示 例如 137 27 23 20 同时约定方次用括号来表示 即ab可表示为a b 由此可知 137可表示为 2 7 2 3 2 0 进一步 7 22 2 20 21用2表示 3 2 20
  • 算法高级(28)-递归、分治、动态规划、贪心、回溯、分支限界几大相似算法比较

    在学习算法的过程中 递归 分治 动态规划 贪心 回溯 分支限界这些算法有些类似 都是为了解决大问题 都是把大问题拆分成小问题来解决 但她们之间还是有一些不同之处的 我来给同学们整理一下 一 算法思想 1 递归算法 recursion alg
  • 有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?

    分析 兔子的对数从第一月开始 1 1 2 3 5 8 规则 从第三月开始 每月的对数是前两月之和 题目问每个月的兔子总数 为更好理解 在此指定具体月数 改为求第20月的兔子总数 本题分别运用三种的方法实现 数组实现 用变量的变化实现 递归实
  • python 中字典{ }的嵌套

    在机器学习中会用字典的嵌套来存储决策树的信息 对绘制树形图有很大的作用 其中嵌套字典的生成是一个递归的过程 如下所示 gt gt gt s a 0 no 1 flippers 0 no 1 maybe b 构造字典 gt gt gt s a
  • 多位个数字 ,不同组合排列之和 (不重复,所有可能的组合之和) PHP

    数组 array 1 2 3 4 多位数也可以 以下是所需第一种方式结果 以下是具体实现代码 public function getSortList array level 1 list for i 0 i lt count array i
  • C语言_函数递归举例

    1 递归和非递归分别实现求第n个斐波那契数 求第 n 个斐波那契数 include
  • 简单的动态规划——装箱问题

    装箱问题 告诉你箱子的容积为多少 告诉你有N件物品和每一件物品的体积 问如何选择物品才能令箱子的剩余容积最小 搜索递归 include
  • 算法--生成1~n的排列

    在暴力求解法中 我们常常要用上枚举一些简单内容以便方便获得解 若要输出整数n的前n个整数的全排列 则按字典序输出为 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 从中我们似乎发现了一些规律 先输出以1开头的排列 再
  • 递归算法深入浅出三:递归求Fibonacci斐波那契数列

    递归算法概述及常见算法列表 传送门 http blog csdn net nthack5730 article details 65537530 斐波那契数列 斐波纳契数列 又称黄金分割数列 指的是这样一个数列 1 1 2 3 5 8 13
  • 递归算法(demo:斐波那契数列的实现,树的遍历,快速排序)

    递归算法 执行代码 并没执行完全的时候调用自己本身 然后等待条件不满足递归的时候 完全执行代码 执行完全后返回上一层 执行未完成的部分 递归算法与for where循环可以相互转换 通过一定的方案达到一样的效果 比如for循环可以通过栈 实

随机推荐

  • 【常用的反监控(winrdlv3)方法winrdlv3】

    常用的反监控 winrdlv3 方法winrdlv3 方案一 使用silent terminal 禁用 sdhelper2 exe和winrdlv3 exe两个程序进程 加密进程终止或者可以只中止sdhelper2则不会加密也不会被管理员发
  • Python手册(Standard Library)--re

    文章目录 re模块 匹配 返回re对象 MatchObject 查找 检索 替换和分割 flags标志 re 模块使 Python 语言拥有全部的正则表达式功能 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象
  • 笔记:JavaScript编译与执行

    1 js的编译与执行 事件循环 单线程语言 JavaScript是单线程语言 即在浏览器中一个页面只有一个线程在执行js代码 进程和线程 假设我们有一家工厂 进程 那么 工厂所拥有的独立资源就相当于系统给我们分配的内存 这是独立的 如果我们
  • Flutter 学习笔记 (二) —— Flutter布局及常用widget总结

    前言 在Flutter里 UI控件就是Widget Widget根据不同的功能可以分为结构元素 如按钮或菜单 文本样式 字体或者颜色方案 布局属性 如填充 对齐 居中 可以这么理解 一个flutter的页面是有一棵树型的Widget组成 包
  • Nginx+Redis+Ehcache:大型高并发与高可用的三层缓存架构总结

    Nginx Redis Ehcache 大型高并发与高可用的三层缓存架构总结 Nginx 对于中间件nginx常用来做流量的分发 同时nginx本身也有自己的缓存 容量有限 我们可以用来缓存热点数据 让用户的请求直接走缓存并返回 减少流向服
  • 电感的特性

    电感的特性 2009 10 19 17 06 jonniyong 分类 工程技术科学 浏览4472次 简单的说电感有虑波 震荡 扼流三个作用 但是具体是怎么来实现的呢 各自的工作原理 还有就是对于这三种用途的电感 那些因素影响他们 也就是说
  • 文本预处理 BOW(Bag Of Words,词袋)和 TF-IDF(Term Frequency-Inverse Document Frequency,词频逆文档频率)

    1 BOW 构建过程 将文本中的词汇提取出来 组成一个词汇表 每篇文档则使用词汇表中的词来表示 形成一个词频向量 忽略词汇之间的顺序关系 只关心词频信息 比如 文本1 The cat sits on the mat 文本2 The dog
  • 分别描述TCP的3次握手和四次挥手的定义、目的和过程

    定义 三次握手是指建立TCP连接协议时 需要在客户端和服务器之间发送三个包 握手过程中传送的包里不包含数据 三次握手完毕后 客户端与服务器才正式开始传送数据 四次挥手是指终止TCP连接协议时 需要在客户端和服务器之间发送四个包 四次挥手完毕
  • C语言 浮点数跟 0 值比较

    include
  • 机器学习算法工程师的自我修养

    https www toutiao com a6647345854191501828 2019 01 18 10 14 00 通往机器学习算法工程师的进阶之路是崎岖险阻的 线性代数 统计学习方法 机器学习 模式识别 深度学习 以及 颈椎病康
  • 模拟量与数字量区别

    目录 传感器的AO与DO DO口 数字信号 AO 模拟信号 模拟信号与数字信号的关系 总结 ADC和DAC 传感器的AO与DO 很多时候 我们购买传感器的时候 能够发现传感器一般都有四个口 拿这款震动传感器作为例子 他有VCC GND AO
  • ANSYS Workbench线圈磁场仿真

    前一篇博客介绍了永磁体磁场的仿真分析 这里再介绍一下线圈磁场的仿真分析 步骤如下 1 利用SolidWorks建立线圈和铁芯模型 线圈内径为10mm 外径为20mm 铁芯直径为10mm 模型如下图所示 2 在Workbench中新建静磁学分
  • ATT&CK红队评估实战靶场(一)

    描述 红队实战系列 主要以真实企业环境为实例搭建一系列靶场 通过练习 视频教程 博客三位一体学习 另外本次实战完全模拟ATT amp CK攻击链路进行搭建 开成完整闭环 后续也会搭建真实APT实战环境 从实战中成长 关于环境可以模拟出各种各
  • JOOQ 代码生成

    Maven Java 项目pom xml 文件
  • 第1143期AI100_机器学习日报(2017-11-04)

    AI100 机器学习日报 2017 11 04 Uber开源深度概率编程语言Pyro 爱可可 爱生活 宾州树库和CTB的Python预处理脚本 hankcs TextBlob Twitter情感分析实战 爱可可 爱生活 Capsule Ne
  • 跨域问题以及在springcloud的gateway中解决跨域问题

    一 什么是跨域问题 跨域问题 当两个页面的域名不一致时 浏览器禁止请求的发起者与服务端发生跨域ajax请求 请求被浏览器拦截的问题 发生跨域问题需要满足的点有 1 两个页面的域名不一致 2 两个页面发生的是ajax请求 这里不允许跨域是浏览
  • echart 设置y轴间隔_分割ECharts的y轴并设置坐标轴间隔

    在 ECharts 图表中的 y 轴的分割段数默认为5 这是由于 yAxis 中的 splitNumber 的决定的 那么我们如果想要在 y 坐标轴上进行更多的分段呢 如何让其刻度间隔变得更加的细致呢 在下文中您会得到答案 yAxis sp
  • javascript cookie session和web storage存储

    众所周知 http是一种无状态存储 现实中的业务需要一定的业务状态 例如某电商网站的用户登录 购物车 如何标示用户和认证一个用户 最早的方案就是cookie存储了 通过引入cookie和session体系机制来维护状态信息 即用户第一次访问
  • 刚刚更新win11,记事本消失怎么处理?你需要注意些什么?

    记录window11的bug hello 我是小索奇 昨天索奇从window10更新到了window11 由于版本不兼容卸载了虚拟机 这是第一个令脑壳大的 算了 还是更新吧 了解了解win11的生态 后期重新装虚拟机 第一个可能问到的问题
  • 递归和非递归

    1 递归就是函数调用函数本身 运行起来就是函数嵌套函数 层层嵌套 所以函数调用 参数堆栈都是不小的开销 但是程序简单 2 非递归就是不断地对参数入栈 出栈 省去了函数层层展开 层层调用的开销 虽然参数出入栈次数多了 但是一般都开辟固定的足够