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

做网站的模版沈阳专业关键词推广

做网站的模版,沈阳专业关键词推广,新网站不收录,网站建设需要上传数据库吗在 C 语言里&#xff0c;函数递归是一种函数调用自身的编程技术。下面开始逐一介绍。 一、什么是递归&#xff1f; 递归其实是⼀种解决问题的⽅法&#xff0c;在C语⾔中&#xff0c;递归就是函数⾃⼰调⽤⾃⼰。 写⼀个史上最简单的C语⾔递归代码&#xff1a; #include <st…

在 C 语言里,函数递归是一种函数调用自身的编程技术。下面开始逐一介绍。

一、什么是递归?

递归其实是⼀种解决问题的⽅法,在C语⾔中,递归就是函数⾃⼰调⽤⾃⼰。

写⼀个史上最简单的C语⾔递归代码:
#include <stdio.h>
int main()
{
    printf("hehe\n");
    main();//main函数中⼜调⽤了main函数
    return 0;
}
上述就是⼀个简单的递归程序,只不过上⾯的递归只是为了演⽰递归的基本形式,不是为了解决问
题,代码最终也会陷⼊死递归,导致栈溢出(Stack overflow)。
1.递归的思想:
把⼀个⼤型复杂问题层层转化为⼀个与原问题相似,但规模较⼩的⼦问题来求解;直到⼦问题不能再被拆分,递归就结束了。所以递归的思考⽅式就是把⼤事化⼩的过程。
递归中的递就是递推的意思,归就是回归的意思。
2.递归的限制条件
递归在书写的时候,有2个必要条件:
递归存在限制条件,当满⾜这个限制条件的时候,递归便不再继续。
每次递归调⽤之后越来越接近这个限制条件。
二、递归举例
1.求n的阶乘
⼀个正整数的阶乘(factorial)是所有⼩于及等于该数的正整数的积,并且0的阶乘为1。
⾃然数n的阶乘写作 n!。
题⽬:计算n的阶乘(不考虑溢出),n的阶乘就是1~n的数字累积相乘。
1.1代码的分析和实现
n的阶乘的公式: n! = n ∗ (n − 1)!
举例:
5!= 5 * 4 * 3 * 2 * 1
4!= 4 * 3 * 2 * 1
所以:5!= 5 * 4!
从这个公式不难看出:如何把⼀个较⼤的问题,转换为⼀个与原问题相似,但规模较⼩的问题来求解的。
n的阶乘和n-1的阶乘是相似的问题,但是规模要少了n。有⼀种有特殊情况是:当 n==0 的时候,n的阶乘是1,⽽其余n的阶乘都是可以通过上⾯的公式计算。
这样就可以写出n的阶乘的递归公式:
那我们就可以写出函数Fact求n的阶乘,假设Fact(n)就是求n的阶乘,那么Fact(n-1)就是求n-1的阶
乘,函数如下:
int Fact(int n)
{
    if (n == 0)
        return 1;
    else
        return n * Fact(n - 1);
}
测试:
#include <stdio.h>
int Fact(int n)
{
    if (n == 0)
        return 1;
    else
        return n * Fact(n - 1);
}
int main()
{
    int n = 0;
    scanf("%d", &n);
    int ret = Fact(n);
    printf("%d\n", ret);
     return 0;
}
结果:
(这里不考虑n太大的情况,n太大容易溢出)
2.画图演练
2.1举例
顺序打印⼀个整数的每⼀位
输⼊⼀个整数m,按照顺序打印整数的每⼀位。
⽐如:
输⼊:1234 输出:1 2 3 4
输⼊:125 输出:1 2 5
2.2代码的分析和实现
拿到这个题目,我们需要想的第一件事就是如何得到每一位数。
如果n是⼀位数,n的每⼀位就是n⾃⼰
n是超过1位数的话,就得拆分每⼀位
1234%10就能得到4,然后1234/10得到123,这就相当于去掉了4
然后继续对123%10,就得到了3,再除10去掉3,以此类推
不断的 %10 和 /10 操作,直到1234的每⼀位都得到;
但是这⾥有个问题就是得到的数字顺序是倒着的
但是这可以发现,最后一位数是最容易得到的,通过%10就可以得到,那我们假设想写⼀个函数Print来打印n的每⼀位,如下表⽰:

Print(n)
如果n是1234,那表⽰为
Print(1234) //打印1234的每⼀位
其中1234中的4可以通过 % 10得到,那么
Print(1234)就可以拆分为两步:
1. Print(1234 / 10) //打印123的每⼀位
2. printf(1234 % 10) //打印4
完成上述2步,那就完成了1234每⼀位的打印
那么Print(123)⼜可以拆分为Print(123 / 10) + printf(123 % 10)

以此类推下去,就有
Print(1234)
==> Print(123) + printf(4)
==> Print(12) + printf(3)
==> Print(1) + printf(2)
==> printf(1)

直到被打印的数字变成⼀位数的时候,就不需要再拆分,递归结束。
那么代码完成也就⽐较清楚:
void Print(int n)
{
    if (n > 9)
    {
        Print(n / 10);
    }
    printf("%d ", n % 10);
}

int main()
{
    int m = 0;
    scanf("%d", &m);
    Print(m);
    return 0;
}

输入和输出的结果:

在这里,我们运用到了大事化小的思路。

把Print(1234) 打印1234每⼀位,拆解为⾸先Print(123)打印123的每⼀位,再打印得到的4
把Print(123) 打印123每⼀位,拆解为⾸先Print(12)打印12的每⼀位,再打印得到的3
直到Print打印的是⼀位数,直接打印就⾏。
2.3画图演练
以1234每一位的打印来推演一下

三、递归与迭代

递归是⼀种很好的编程技巧,但是和很多技巧⼀样,也是可能被误⽤的,就像举例1⼀样,看到推导的公式,很容易就被写成递归的形式:
int Fact(int n)
{
    if (n == 0)
        return 1;
    else
        return n * Fact(n - 1);
}
Fact函数是可以产⽣正确的结果,但是在递归函数调⽤的过程中涉及⼀些运⾏时的开销。
在C语⾔中每⼀次函数调⽤,都需要为本次函数调⽤在内存的栈区,申请⼀块内存空间来保存函数调⽤期间的各种局部变量的值,这块空间被称为运⾏时堆栈,或者函数栈帧。
函数不返回,函数对应的栈帧空间就⼀直占⽤,所以如果函数调⽤中存在递归调⽤的话,每⼀次递归函数调⽤都会开辟属于⾃⼰的栈帧空间,直到函数递归不再继续,开始回归,才逐层释放栈帧空间。
所以如果采⽤函数递归的⽅式完成代码,递归层次太深,就会浪费太多的栈帧空间,也可能引起栈溢出的问题。
所以如果不想使⽤递归,就得想其他的办法,通常就是迭代的⽅式(通常就是循环的⽅式)。
⽐如:计算 n 的阶乘,也是可以产⽣1~n的数字累计乘在⼀起的。
1.举例
求第n个斐波那契数
以计算 factorial(5) 为例,执行过程如下:
factorial(5) 调用 5 * factorial(4)。
factorial(4) 调用 4 * factorial(3)。
factorial(3) 调用 3 * factorial(2)。
factorial(2) 调用 2 * factorial(1)。
factorial(1) 满足基本情况,返回 1。
然后逐步回溯计算:
factorial(2) 返回 2 * 1 = 2。
factorial(3) 返回 3 * 2 = 6。
factorial(4) 返回 4 * 6 = 24。
factorial(5) 返回 5 * 24 = 120。
由此可以看出,这里不适合使用递归,用迭代的方式效率更高。
递归的优缺点
优点:
代码简洁:递归可以让代码更加简洁、易读,尤其是处理一些具有递归结构的问题,如树的遍历、分治算法等。
易于理解:对于某些问题,递归的思路更贴合人类的思维方式,更容易设计和实现。
缺点:
性能问题:递归调用会频繁地进行函数调用和返回操作,带来额外的开销,可能会导致性能下降。
栈溢出风险:如果递归深度过大,会导致栈空间耗尽,引发栈溢出错误。
注意事项
要确保递归函数包含基本情况,防止无限递归。
注意递归深度,避免栈溢出。在必要时,可以考虑使用迭代(循环)来替代递归。
迭代是指基于一个初始值,按照特定的规则反复执行一系列操作,每一次执行都会对前一次的结果进行更新,直到满足某个终止条件为止。这个过程可以看作是对一个状态不断进行修改和演进的循环过程。
递归和迭代对比
执行效率:
迭代:通常情况下,迭代的执行效率相对较高,因为它避免了函数调用栈的频繁操作,只是在循环结构内进行简单的指令重复执行,减少了额外的开销。
递归:递归由于不断地进行函数调用和返回,会有一定的时间和空间开销,尤其是在递归深度较大时,可能会出现栈溢出等性能问题。
代码可读性:
迭代:对于一些简单逻辑,迭代代码的结构清晰,易于理解和调试,直接通过循环条件和循环体就能明白代码的执行流程。
递归:递归代码在处理具有递归结构的问题(如树的遍历、分治算法等)时,代码可能更简洁,更符合人们对问题的分解式思考方式,但对于初学者或者复杂逻辑,理解起来可能有一定难度。

迭代和递归各有优缺点,在实际编程中,需要根据问题的特点、性能要求和代码的可读性来选择合适的方法。有时候,迭代和递归可以相互转换,通过合理的设计和优化,可以提高代码的性能和可维护性。

http://www.dtcms.com/wzjs/347706.html

相关文章:

  • 免费建站网站seoul是什么意思
  • 手机酒店网站建设网站优化排名易下拉稳定
  • 东莞建设网办事指南seo顾问什么职位
  • 网站seo优化方案设计品牌词优化
  • 建设安全带官方网站互联网营销师证书骗局
  • 做网站原型现成的框架产品推广方案怎么做
  • 1高端网站建设软文推广一般发布在哪些平台
  • 秋长网站建设seo网站诊断顾问
  • 学院网站的作用社会新闻最新消息
  • 网站是不是每年都要续费流氓网站
  • 二手商品网站制作电子商务营销策略
  • 网站title的写法seo关键词优化的技巧和方法
  • 在什么网站做知识禁毒竞赛软文推广文章
  • 南通网站制作建设代运营哪家公司最靠谱
  • 做印章的网站优秀品牌策划方案
  • 响应式网站可以做缩放图吗关于网络推广的方法
  • seo网站做推广的公司广点通广告投放平台登录
  • 下载新版app免费下载安装seo免费诊断联系方式
  • 致力于做服务更好的网站建设公司2024很有可能再次封城吗
  • 网站建设的相关资料万能搜索网站
  • 伪原创网站百度图片搜索引擎
  • 住房和城乡建设部网站规范答疑网站收录查询系统
  • 如何免费自己做网站湖南企业网站建设
  • 成都装修设计公司厦门seo关键词优化培训
  • 重庆建网站常用的关键词挖掘工具有哪些
  • 网站建设深圳如何写软文
  • 有专门教做儿童美食的网站吗网络营销师报名入口
  • 企业网站的分类有哪三种大数据查询个人信息
  • 郑州手机网站制作公司哪家好企业网站推广可以选择哪些方法
  • 深圳红酒网站建设长沙线上引流公司