递归和非递归

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(使用前将#替换为@)

递归和非递归 的相关文章

  • 树的遍历(bfs+递归)

    题目描述 一个二叉树 树中每个节点的权值互不相同 现在给出它的后序遍历和中序遍历 请你输出它的层序遍历 输入描述 第一行包含整数 N 表示二叉树的节点数 第二行包含 N 个整数 表示二叉树的后序遍历 第三行包含 N个整数 表示二叉树的中序遍
  • 关于二叉树的几种遍历方法

    转载请注明出处 http blog csdn net pony maggie article details 38390513 作者 小马 一 二叉树的一些概念 二叉树就是每个结点最多有两个子树的树形存储结构 先上图 方便后面分析 1 满二
  • 1123. 最深叶节点的最近公共祖先

    文章目录 Tag 题目来源 题目解读 解题思路 方法一 递归 写在最后 Tag 递归 最近公共祖先 二叉树 题目来源 1123 最深叶节点的最近公共祖先 865 具有所有最深节点的最小子树 此二题系重复的题目 题目解读 题目意思很明确 找出
  • 称重问题递归解法

    用天平称重时 我们希望用尽可能少的砝码组合称出尽可能多的重量 如果只有5个砝码 重量分别是1 3 9 27 81 则它们可以组合称出1到121之间任意整数重量 砝码允许放在左右两个盘中 本题目要求编程实现 对用户给定的重量 给出砝码组合方案
  • 链表面试题-合并两个有序单链表(递归和非递归)

    题目描述 合并两个有序单链表 使得最终的链表也是递增的 节点的结构 typedef struct ListNode ListNode next int data Node 递归 Node MergeListR Node Head1 Node
  • Python解决最长子串问题

    设有两个字符串abaabba和bbbabaa 问它们的最长子串是什么 这个问题的一个应用就是比较两个病毒的基因 从而给出两者的相似度 这里我们用递归方法解决这个难题 输入参数显然是两个字符串s1和s2 递归边界是s1和s2中至少有一个是空字
  • 【华为机试题解】奥特曼打怪兽

    大概题意 在一个N N的正方形区域 每个小格可能有三种状态 值为0 正常可通过 值为1 奥特曼可通过 同时还可以消灭怪兽 消灭后值变为0 消灭怪兽数量 1 值为 1 有大石头 奥特曼无法通过 奥特曼需要先从上往下走 这个过程只能向下或者向右
  • 算法竞赛进阶指南 递归实现组合型枚举

    文章目录 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
  • 递归求斐波那契数列

    斐波那契数列 题目描述 编写一个函数 求斐波那契数列的第n项的值 首先 对于斐波那契数列 我们是非常熟悉了 对斐波那契定义为如下 f 0 0 f 1 0 f 2 1 f n f n 1 f n 2 其中n gt 1 对于这种求斐波那契数列第
  • EXCEL-VBA:递归遍历文件夹及子文件夹中的文件

    Const SearchPath D PDF Dim DicList FileList I FileName FilePath Set DicList CreateObject Scripting Dictionary Set FileLi
  • x的n次幂

    题目描述 实现 pow x n 即计算 x 的 n 次幂函数 样例 输入 2 00000 10 输出 1024 00000 说明 100 0 lt x lt 100 0 n 是 32 位有符号整数 其数值范围是 2147483648 214
  • 如何用递归解决逆波兰表达式问题?

    描述 逆波兰表达式是一种把运算符前置的算术表达式 例如普通的表达式2 3的逆波兰表示法为 2 3 逆波兰表达式的优点是运算符之间不必有优先级关系 也不必用括号改变运算次序 例如 2 3 4的逆波兰表示法为 2 3 4 本题求解逆波兰表达式的
  • 自学C之递归理解

    一 理解概念 C语言允许一个函数调用自身 这种过程被称为递归 Recursion 程序使用递归处理特殊的问题 如阶乘 Ackermann函数 反序等等 实际上 如果不考虑运行时内存的开消 任何使用赋值语句 if else和while结构的函
  • HJ61 放苹果

    题目 HJ61 放苹果 题解 递归 f m n 表示将m个苹果放在n个盘子中所有的放法 当n gt m时 一定有盘子空着 等效于将m个苹果放到m个盘子中 即f m n f m m 当 n lt m时 没有空盘子 那么每个盘子至少有一个 那么
  • 数据结构 ——二叉树 前序、中序、后序、层次遍历及非递归实现 查找、统计个数、比较、求深度的递归实现

    一 基本概念 每个结点最多有两棵子树 左子树和右子树 次序不可以颠倒 性质 1 非空二叉树的第n层上至多有2 n 1 个元素 2 深度为h的二叉树至多有2 h 1个结点 满二叉树 所有终端都在同一层次 且非终端结点的度数为2 在满二叉树中若
  • Leetcode题解——26.树的子结构

    题目地址 剑指 Offer 26 树的子结构 力扣 LeetCode 目录 一 解题思路 一 大体思路 二 Search函数 三 Judge函数 二 代码实现 三 拓展思考 一 解题思路 一 大体思路 对于二叉树类的题目 一般会使用递归或层
  • 简单的动态规划——装箱问题

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

    描述 给定一个由不同的小写字母组成的字符串 输出这个字符串的所有全排列 我们假设对于小写字母有 a lt b lt lt y lt z 而且给定的字符串中的字母已经按照从小到大的顺序排列 输入 输入只有一行 是一个由不同的小写字母组成的字符

随机推荐

  • 【常用的反监控(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 非递归就是不断地对参数入栈 出栈 省去了函数层层展开 层层调用的开销 虽然参数出入栈次数多了 但是一般都开辟固定的足够