当前位置: 首页 > news >正文

函数(递归)

递归:程序调用自身编程技巧称为递归。

       在学习递归前需要粗略的了解一下内存,内存分为三类,分别是栈区、堆区和静态区。对于栈区来说,每调用一次函数都会为本次函数开辟一块空间,然而栈区也是有空间限制的,随即函数调用存在限制条件(当满足这个限制条件是递归便不再继续),且每次递归调用后越来越接近这个限制条件。超过这个限制会出现栈溢出的现象。

现在写一个简单的代码看一下栈溢出会出现怎么样的现象。

int main()
{printf("NX\n");main();return 0;
}

递归题目类型(既可以用递归也可以用非递归(简称迭代))

        1.打印一个数字的每一位且按照顺序。例:1024->1 0 2 4 ;

递归法

       递归是由里往外,先执行最里层的函数,函数执行完再逐渐返回调用的函数直至函数全部执行完返回到主函数里。这个题目就是不断地取余取模,一直重复这两个操作。它可以通过抹去尾位不断调用函数直至打印最高位,下面这个图演示了调用函数的过程:

 代码实现:

void print_digit(int n)
{if (n){print_digit(n / 10);printf("%d ", n % 10);}
}int main()
{int n = 0;scanf("%d", &n);print_digit(n);return 0;
}

 迭代法

       这个方法需要抹去最高位数并打印出来,在这之前需要知道这个数的位数。接着对这个数进行相同位数取模、打印,取余减小位数为了打印下一位数字,这个相同位数在打印中不断变化(减小一位),然后就是重复之前的操作。

       举一次例子:通过计算得到1024是一个四位的数字,然后计算出就是相同位数1000,先取模1024/1000并打印数字1,最高位就打印好了,其次就是取余1024%1000=24将其值赋值给n,相同位数随即也要减小一位1000/10;然后就是while循环重复。

代码实现: 

int digit(int n)
{int count = 0;while (n){n = n / 10;count++;}return count;
}int main()
{int n = 0;scanf("%d", &n);int i = 0;int count = 0;int ret = 1;count = digit(n);//调用函数的原因是不改变n的值(利用形参不改变实参的值)for (i = 1; i < count; i++){ret = ret * 10;//计算相同位数}while (n){printf("%d ", n / ret);n = n % ret;//取余ret = ret / 10;//为了相同位数取模}return 0;
}
       2.实现n的k次方。例:2 3->8;

递归法

       限制条件是(k>0)满足调用函数,不满足返回1。下图展示:

代码实现: 

int factorial(int n, int k)
{if (k > 0){return n * factorial(n, k - 1);}else{return 1;}
}int main()
{int n = 0;int k = 0;scanf("%d %d", &n, &k);int sum = factorial(n, k);printf("%d\n", sum);return 0;
}

迭代法

       通过循环相乘有点类似累乘,代码也更少一点。代码实现:

int main()
{int n = 0;int k = 0;int i = 0;int num = 1;scanf("%d %d", &n, &k);for (i = 1; i <= k; i++){num = num * n;//n的k次方}printf("%d\n", num);return 0;
}
       3.斐波那契数。例:1,1,2,3,5,8,13,......

递归法

       限制条件(n<3)。满足返回1,不满足调用函数直至返回一个数字。下面是第五个斐波那契数需要调用的斐波那契数,仔细看会发现有一些斐波那契数重复计算或调用(3,2,1),这大大增加计算的时间,假设需要计算一个很大很大的斐波那契数那重复计算的次数会更多,所以有时候并不是代码越简单越好,或任何场景使用递归都不是明智之举,需要具体问题具体分析。

代码实现: 

int fibonacci(int n)
{if (n < 3)return 1;elsereturn fibonacci(n - 1) + fibonacci(n - 2);
}int main()
{int n = 0;scanf("%d", &n);int ret = fibonacci(n);printf("%d\n", ret);return 0;
}

迭代法 

 简单明了的表明意图,循环直接算斐波那契前两项,通过不断复制避免重复计算。代码演示:

int main()
{int n = 0;int i = 0;int a = 1;int b = 1;long long c = 1;//考虑斐波那契数会是一个巨大的数scanf("%d", &n);while (n > 2){c = a + b;a = b;b = c;n--;//循环条件}printf("%d\n", c);return 0;
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【JAVA】数据类型及变量
  • Android Navigation 组件原理和使用教程
  • 面试问题:React基本概念,和所遇到的CPU和IO问题
  • ​必胜客礼品卡回收多少钱,回收平台哪家好
  • Java面试题--JVM大厂篇之深入解析JVM中的Serial GC:工作原理与代际区别
  • spdlog源码学习:std::unique_ptr订制删除器,guard用法,以及decltype
  • Python面试整理-Python中的函数定义和调用
  • Linux工具相关介绍
  • 网络通讯实验报告
  • jenkins 使用教程
  • 3226 使两个整数相等的位更改次数
  • 鸿蒙OpenHarmony Native API【HiLog】
  • PyQt5学习路线
  • 上海昇腾AI训练营笔记
  • mysql8和mysql5版本在使用mybatis框架时的注意事项
  • Babel配置的不完全指南
  • const let
  • github指令
  • MyEclipse 8.0 GA 搭建 Struts2 + Spring2 + Hibernate3 (测试)
  • quasar-framework cnodejs社区
  • Shell编程
  • win10下安装mysql5.7
  • 爱情 北京女病人
  • 深入浅出Node.js
  • 使用parted解决大于2T的磁盘分区
  • 线上 python http server profile 实践
  • 异步
  • 正则与JS中的正则
  • 【运维趟坑回忆录 开篇】初入初创, 一脸懵
  • 分布式关系型数据库服务 DRDS 支持显示的 Prepare 及逻辑库锁功能等多项能力 ...
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • ​必胜客礼品卡回收多少钱,回收平台哪家好
  • ​一帧图像的Android之旅 :应用的首个绘制请求
  • # .NET Framework中使用命名管道进行进程间通信
  • #include到底该写在哪
  • (¥1011)-(一千零一拾一元整)输出
  • (70min)字节暑假实习二面(已挂)
  • (html5)在移动端input输入搜索项后 输入法下面为什么不想百度那样出现前往? 而我的出现的是换行...
  • (Java数据结构)ArrayList
  • (Windows环境)FFMPEG编译,包含编译x264以及x265
  • (第61天)多租户架构(CDB/PDB)
  • (二十三)Flask之高频面试点
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (附源码)计算机毕业设计SSM基于java的云顶博客系统
  • (几何:六边形面积)编写程序,提示用户输入六边形的边长,然后显示它的面积。
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (算法)大数的进制转换
  • (一)UDP基本编程步骤
  • (转) RFS+AutoItLibrary测试web对话框
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • ./include/caffe/util/cudnn.hpp: In function ‘const char* cudnnGetErrorString(cudnnStatus_t)’: ./incl
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .NET Core 版本不支持的问题
  • .net core 控制台应用程序读取配置文件app.config