【手撕C语言基础】递归

news2024/12/24 9:55:44
  • (꒪ꇴ꒪ ),hello我是祐言
  • 博客主页:C语言基础,Linux基础,软件配置领域博主🌍
  • 快上🚘,一起学习!
  • 送给读者的一句鸡汤🤔:
  • 集中起来的意志可以击穿顽石!
  • 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏

       递归是编程中的一个重要概念,它允许函数调用自身以解决复杂的问题。在这篇博客中,我们将深入探讨C语言中的递归。我们将首先解释什么是递归,然后通过一些例子详细介绍如何在C语言中使用递归。

一、什么是递归?


        递归是一种解决问题的方法,它将一个问题分解为更小的子问题,直到问题可以直接解决。使用递归的函数会自我调用,并且每次调用都会缩小问题的规模,这样直到可以直接计算结果。重要的是,每个递归调用都应该离解决问题更近一步,并且有一个清晰的终止条件。

二、如何在C语言中使用递归?

        在C语言中,递归函数的定义和普通函数一样,只是它在函数体内部调用自己。以下是一个简单的递归函数的例子:

void recursiveFunction() {
    ... // some code
    recursiveFunction();  // 调用它自己
    ... // some code
}


        注意,这样的函数会无限地调用自己,因此我们需要设定一个终止条件。以下是一个更实际的例子,这个函数计算一个非负整数的阶乘:

unsigned long long factorial(unsigned int n) {
    if (n == 0) {  
        return 1;
    } else {
        return n * factorial(n - 1);  
    }
}


三、递归的例子


        让我们通过一些具体的例子来深入理解递归在C语言中的应用。
1.求1-100的和

        递归求和是一个简单易懂的递归例子,以下是一个示例代码:

#include <stdio.h>

int sumn(int n) {
    if (n == 1) {
        return 1;
    } else {
        return n + sumn(n - 1);
    }
}

int main() {
    int n = 1000;
    int result = sumn(n);
    printf("从1到%d的和为:%d\n", n, result);
    return 0;
}



       我们 首先,在代码开头引入了stdio.h头文件,这是C语言中用于输入输出的标准库。
        然后,定义了一个名为sumn的递归函数,该函数接受一个整数参数n,表示要计算的范围上限。
        在函数内部,首先判断基本情况,即当n等于1时,直接返回1,表示从1到1的和为1。
        如果n不等于1,就进行递归调用。递归调用的过程是将n减1,然后再调用sumn函数本身,传入减去1后的n。这样就将原问题转化为更小的子问题。
        递归调用返回后,会得到子问题的解,即从1到n-1的和。然后将n与子问题的解相加,得到从1到n的和。


2.Fibonacci数列

 

        Fibonacci数列是一个经典的递归问题。在这个数列中,每个数字是前两个数字的和。以下是一个递归函数来计算Fibonacci数列的第n项:

unsigned long long fibonacci(unsigned int n) {
    if (n <= 1) {  // base cases
        return n;
    } else {
        return fibonacci(n - 1) + fibonacci(n - 2);  // recursive case
    }
}

3.汉诺塔问题


        汉诺塔是另一个著名的递归问题。在这个问题中,我们有三根柱子和n个大小不同的盘子,开始时所有盘子按大小顺序堆在一根柱子上。我们的目标是将所有盘子移动到另一根柱子上,每次只能移动一个盘子,并且任何时候大盘子都不能在小盘子上面。以下是一个使用递归解决汉诺塔问题的函数:

void hanoiTower(int n, char from_rod, char to_rod, char aux_rod) {
    if (n == 1) {
        printf("\n 将盘子 1 从柱子 %c 移动到柱子 %c", from_rod, to_rod);
        return;
    }
    hanoiTower(n - 1, from_rod, aux_rod, to_rod);
    printf("\n 将盘子 %d 从柱子 %c 移动到柱子 %c", n, from_rod, to_rod);
    hanoiTower(n - 1, aux_rod, to_rod, from_rod);
}


四、递归的优点和缺点


        递归提供了一种强大而优雅的解决问题的方法,可以让我们以直观的方式解决复杂的问题。然而,递归也有其缺点。每次函数调用都会消耗一些内存和处理器时间。如果递归调用的层数太多,可能会导致栈溢出。此外,对于某些问题,非递归解决方案可能更有效。

1.优点


        (1)代码简洁易读:递归的代码通常比使用循环的代码更简洁,更易于理解。递归的解决方案通常直接对应于问题的定义,因此更符合人的思维方式。

       (2) 解决复杂问题:递归非常适合解决那些可以自然地分解为更小实例的问题,例如排序算法,搜索算法,动态规划等。

2.缺点


        (1)空间和时间效率:递归函数由于需要反复调用自身,会产生大量的函数调用开销,可能引起栈溢出。每次函数调用都会在栈上创建一个新的环境以存储局部变量、返回地址等信息,如果递归调用的深度过大,会消耗大量的栈空间,甚至导致栈溢出。

        (2)递归深度限制:大多数编程语言(包括C)都对递归深度有限制。如果递归调用深度超过这个限制,程序就会终止。

        (3)可能引发复杂性:虽然递归在某些情况下可以简化问题,但在其他情况下,它可能会使问题变得更加复杂。理解和调试递归函数可能需要更多的思考和时间。

五、如何写出好的递归函数?

     

        1.确定基本情况:基本情况是递归结束的条件,通常是问题的一个简单实例。在定义递归函数时,首先要确定基本情况。

        2.确保你的函数在每次递归调用时都向基本情况靠近:你的函数应该在每次递归调用后,问题的规模都有所减小,以确保最终能达到基本情况。

        3.通过测试验证你的函数:由于递归函数的复杂性,测试对于验证其正确性尤为重要。

六、总结


        递归是编程中的一个强大工具,它能让我们以简洁和直观的方式解决复杂问题。然而,递归也有其复杂性和效率问题。作为一名优秀的程序员,理解何时以及如何使用递归是非常重要的。

附加小问题:

        这是一道华为的笔试题,如果你能做出来,那么你对递归和指针的理解已经达到一定水平啦。

下面函数实现数组a元素的逆转,k为数组的元素个数。请填写空白处使其完整。

void  recur(int a[],  int k)
{
    int  tmp;
    if( __ )
    {
        recur(  __ ,  __ );
        tmp = a[0];
        a[0] = a[k-1];
        a[k-1] = tmp;
    }
}

        答案在评论区!

更多C语言相关文章,关注专栏:

手撕C语言

📢写在最后

  • 今天的分享就到这啦~
  • 觉得博主写的还不错的烦劳 一键三连喔~
  • 🎉感谢关注🎉

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/767224.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

数据结构(王道)——数据结构之 二叉树

一、数据结构之 二叉树概念&#xff1a; 特殊的二叉树结构&#xff1a; 满二叉树完全二叉树 二叉排序树 平衡二叉树 二叉树基本概念总结&#xff1a; 二、二叉树的常用性质&#xff1a; 1、叶子结点比二分支结点多一个

汽车的空气悬架的功能以及发展趋势

空气悬架能实现什么功能以及发展趋势 了解空气悬架之前,首先得快速了解什么是悬架。 教科书说法是: 悬架系统是汽车的车架与车桥或车轮之间的一切传力连接装置的总称。悬架系统基本构成有弹性元件(各类弹簧,缓冲作用);减震元件(减震器,减震作用);导向机构(控制臂等…

技术分享:如何用pytest_addoption切换自动化测试环境?

前言 在目前互联网公司中&#xff0c;都会存在多个测试环境&#xff0c;那么当我们编写的自动化想要在多套测试环境下进行运行时&#xff0c;如何使用&#xff1f; 大多数人想到的可能是通过将我们自动化代码中的地址修改成不同环境。 但是这时候就会增加一些工作量&#xf…

智安网络|移动安全的转型:零信任如何重新定义格局

数字化转型和远程/移动办公的常态化已经成为许多企业的现实。这一转变为企业带来了许多便利&#xff0c;但同时也引入了前所未有的风险&#xff0c;涉及员工的隐私、个人身份和特权访问凭证。尤其是在经济衰退和疫情的持续影响下&#xff0c;许多企业不得不在提高生产力的同时面…

260道网络安全工程师面试题汇总(附答题解析+配套资料)

由于我之前写了不少网络安全技术相关的文章和回答&#xff0c;不少读者朋友知道我是从事网络安全相关的工作&#xff0c;于是经常有人私信问我&#xff1a; 我刚入门网络安全&#xff0c;该怎么学&#xff1f; 想找网络安全工作&#xff0c;应该要怎么进行技术面试准备&…

Linux gdb汇编调试

文章目录 一、示例代码二、gdb汇编指令2.1 step/stepi2.2 next/nexti2.3 info registers2.4 set2.5 x2.6 rip寄存器2.7 rip 寄存器 参考资料 一、示例代码 &#xff08;1&#xff09; #include <stdio.h>int add(int a, int b) {return a b; }int main() {int a 3;in…

Linux安装或者升级cmake,例子为v3.10.2升级到v3.25.0(自己指定版本)

1. 引言 系统: ubuntu 1804 64位点我进入清华源-GCC链接: https://cmake.org/files/v3.25/ 先卸载自己电脑上的cmake。 cmake -version sudo apt-get autoremove cmake2. 下载编译指定版本cmake 可以根据自己的需求下载对应版本的cmake。 cd ~ && mkdir cmake &…

3Ds max图文教程:高精度篮球3D建模

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 第 1 步。使用以下设置在顶部视口上创建球体&#xff1a; 第 2 步。将球体转换为可编辑的多边形&#xff1a; 第 3 步。转到 Edge 子对象级别并剪切以下边缘&#xff1a; 第 4 步。选择以下边&#xff0c;然…

农产品后台管理系统(一)——项目总览

后端技术栈 SpringBoot2.xMybatis-plusMysql8.0redisjsoup&#xff08;测试爬取数据&#xff09; 前端技术栈 Vue3EchartsAxios前端组件&#xff1a;element-china-area-data、element-plus 项目概览截图 登录界面 注册界面 农产品发布界面 用户管理界面 用户画像界面 订单…

【JavaEE】Tomcat的安装和使用、创建Mevan项目使用Servlet写一个程序

目录 前言 一、Tomcat的下载和安装 二、写一个简单的Servlet项目 1、创建一个Maven项目 2、引入依赖 3、创建目录 4、编写Servlet代码。 5、打包程序 6、将程序部署到Tomcat上 7、验证程序运行结果 三、在IDEA上安装Smart Tomcat插件 四、Servlet中的一些常见错误 …

欧姆龙plc之间的以太网通讯

捷米特JM-ETH-CP转以太网模块控&#xff0c;用于欧姆龙 CP1L/ CP1E/ CP1H 系列 PLC 的以太网数据采集&#xff0c;非常方便构建生产管理系统。 支持 FINS/UDP、FINS/TCP 以太网协议通信&#xff0c;支持上位机软件&#xff08;组态王、MCGS、力控、KepWare OPC 服务器等&#…

怎么把pdf转换成jpg图片?这几种方法纯干货

怎么把pdf转换成jpg图片&#xff1f;PDF和JPG是两种常见的文件格式&#xff0c;它们各自有自己的应用场景和优势。PDF格式通常用于创建和共享文档&#xff0c;因为它可以保留文档中的格式和布局&#xff0c;而且可以在几乎所有设备上查看。JPG格式通常用于存储和共享图像文件&a…

5款实用的软件,能帮你解决一些工作和生活中的问题

​ 我乐于分享一些有用的软件给大家&#xff0c;让大家的工作更高效。今天&#xff0c;我要向大家推荐五款实用的软件&#xff0c;它们都能帮你解决一些工作和生活中的问题。 桌面整理——蜂窝桌面整理 ​ 蜂窝桌面整理是一个桌面整理软件&#xff0c;可以让你在桌面上创建和…

OpenCV for Python 学习第四天 :通道的获取与合并

上一篇博客&#xff0c;我们学习了如何通过更快的item()和itemset()的方法访问图片&#xff0c;以及了解了图像的兴趣位置的获取方法&#xff0c;那么今天&#xff0c;我们将学习通道的处理方法&#xff0c;通过通道的拆分和合并的实例&#xff0c;让大家更好的了解咱们有关于B…

论文解读:LaMa:Resolution-robust Large Mask Inpainting with Fourier Convolutions

论文&#xff1a;https://arxiv.org/pdf/2109.07161.pdf 代码&#xff1a; GitHub - advimman/lama: &#x1f999; LaMa Image Inpainting, Resolution-robust Large Mask Inpainting with Fourier Convolutions, WACV 2022 目录 1 摘要&#xff1a; 2 主要贡献&#xff…

Bland-Altman LOA:衡量测量方法一致性的统计分析方法,也可用来做分割评价指标

Bland-Altman LOA&#xff08;Limits of Agreement&#xff09;是一种用于评估两种测量方法一致性的常用统计分析方法。 在医学研究和临床实践中&#xff0c;我们经常会面临不同测量方法之间的比较和评估问题。为了确定两种测量方法是否能够得出相似的结果&#xff0c;我们需要…

D. Accommodation

Problem - 1804D - Codeforces 思路&#xff1a;首先我们可以统计一下开着灯的个数&#xff0c;对于一个卧室的来说&#xff0c; 不会存在让灯减少的情况&#xff0c;而对于两个卧室的来说&#xff0c;存在4种情况&#xff0c;00&#xff0c;01&#xff0c;10&#xff0c;11&am…

hosts文件锁定,如何修改hosts文件权限

hosts文件能够让我们配置域名和IP的映射关系&#xff0c;方便局域网的用户&#xff0c;可是有的用户想在hosts里添加修改&#xff0c;发现host文件被锁死&#xff0c;host文件左下角出现一个&#x1f512;&#xff0c;怎么办呢&#xff0c;如何修改hosts文件权限。 应用程序-实…

【DevOps】Atlassian插件开发指南

本文以Bamboo插件开发为例&#xff0c;记录一下插件开发过程。 一、简介 Atlassian Bamboo 6.9.1 是一款持续集成和持续交付&#xff08;CI/CD&#xff09;工具&#xff0c;支持使用插件扩展其功能。如果需要开发自己的 Bamboo 插件并添加到 Bamboo 中&#xff0c;则可以参考…

OpenCv之图像形态学(二)

目录 一、形态学梯度 二、顶帽操作 三、黑帽操作 一、形态学梯度 梯度原图 - 腐蚀腐蚀之后原图边缘变小&#xff0c;原图 - 腐蚀 就可以得到腐蚀掉的部分&#xff0c;即边缘 案例代码如下: import cv2 import numpy as np# 导入图片 img cv2.imread(6.jpg)# 注意调节kern…