【C】-递归

news2025/6/7 15:25:46

1、递归概念

递归(Recursion)是编程中一种重要的解决问题的方法,其核心思想是函数通过调用自身来解决规模更小的子问题,直到达到最小的、可以直接解决的基准情形(Base Case)。
在这里插入图片描述

核心:自己调用自己
必要条件:

  • 基准情形(base case):函数不再递归调用的终止条件,避免无限循环;
  • 递归步骤(Recursive step):将原问题分解为规模更小的子问题,并通过递归调用解决。(每次递归调用后,越来越接近终止条件).

2、递归的应用场合

  • 数学问题:阶乘计算、斐波那契数列、最大公约数
  • 数据结构遍历:树的遍历、图的深度优化搜索、链表操作(反转、查找)
  • 分治算法:快速排序、归并排序、汉诺塔问题
  • 其它:目录结构遍历、格式解析(JSON/XML)

3、递归的实现

/* 阶乘函数 */
int factorial(int n) {
    // 基准情形
    if (n == 0) return 1;
    // 递归步骤
    return n * factorial(n - 1);
}

/* 二叉树遍历,前序 */
struct TreeNode {
    int data;
    struct TreeNode* left;
    struct TreeNode* right;
};

void preOrderTraversal(struct TreeNode* root) {
    if (root == NULL) return;  // 基准情形
    printf("%d ", root->data);  // 访问根节点
    preOrderTraversal(root->left);  // 递归左子树
    preOrderTraversal(root->right);  // 递归右子树
}

尾递归(Tail Recursion)
尾递归是递归编程的一种特殊形式,其核心特点是:递归调用是函数的最后一个操作,且返回值不参与任何计算。这种结构允许编译器将递归优化为迭代,避免栈溢出风险。
(1)普通递归 vs 尾递归

// 普通递归阶乘(非尾递归):递归调用后还需进行额外计算(如乘法、加法)
int fact(int n) {
    if (n == 0) return 1;
    return n * fact(n-1);  // 递归调用后需进行乘法运算
}

// 尾递归阶乘:递归调用是最后一步,结果直接返回。
int fact_tail(int n, int acc) {
    if (n == 0) return acc;
    return fact_tail(n-1, n * acc);  // 递归调用是最后操作,无后续计算
}

(2)关键特征

  • 最后操作:递归调用必须是函数的最后一条语句。
  • 无后续计算:返回值直接来自递归调用,不参与额外运算。
  • 累加器参数:通常引入额外参数(如acc)保存中间结果

(3)尾递归的优缺点
优点

  • 避免栈溢出:优化后等效于迭代,栈空间复杂度为 O (1)。
  • 代码简洁:保持递归的逻辑清晰性,同时获得迭代的性能。

缺点

  • 依赖编译器优化:C 语言标准并未强制要求尾递归优化,部分编译器(如 GCC)会自动优化,但并非所有平台都支持。
  • 可读性降低:引入累加器参数可能使代码更难理解(如斐波那契的尾递归版本)。

4、递归的优缺点

优点

  • 代码简洁:直接表达问题的数学定义,减少代码量。
  • 易于理解:对于递归定义的问题(如树结构),逻辑更清晰。
  • 解决复杂问题:适合分治策略,如排序和搜索算法。
    缺点
  • 性能开销:递归调用会消耗栈空间,可能导致栈溢出(Stack Overflow)。
  • 效率问题:某些递归(如斐波那契数列)存在大量重复计算,可用 记忆化(Memoization) 优化。
  • 调试困难:多层递归调用的执行流程复杂,调试时堆栈跟踪较深。

5、常见相关问题

(1)必须确保基准情形存在,否则会导致无限递归,最终引发栈溢出。
(2)注意递归深度,过深建议调整为循环或迭代。
(3)使用打印语句跟踪递归过程,或结合调试器查看调用栈。

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

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

相关文章

飞马LiDAR500雷达数据预处理

0 引言 在使用飞马D2000无人机搭载LiDAR500进行作业完成后,需要对数据进行预处理,方便给内业人员开展点云分类等工作。在开始操作前,先了解一下使用的软硬件及整体流程。 0.1 外业测量设备 无人机:飞马D2000S激光模块&#xff…

嵌入式鸿蒙开发环境搭建操作方法与实现

Linux环境搭建镜像下载链接: 链接:https://pan.baidu.com/s/1F2f8ED5V1KwLjyYzKVx2yQ 提取码:Leun vscode和Linux系统连接的详细过程1.下载Visual Studio Code

QT常用控件(1)

控件是构成QT的基础元素,例如Qwidget也是一个控件,提供了一个‘空’的矩形,我们可以往里面添加内容和处理用户输入,例如:按钮(QpushButton),基础显示控件(Lable&#xff…

明基编程显示器终于有优惠了,程序员快来,错过等一年!

最近618的活动已经陆续开始了,好多人说这是买数码产品的好时候,作为一名资深程序员,我做了不少功课,决定给自己升级办公设备,入手明基 RD 系列的显示器,这是市面上首家专注于我们程序员痛点和需求的产品&am…

【计算机网络】非阻塞IO——select实现多路转接

🔥个人主页🔥:孤寂大仙V 🌈收录专栏🌈:计算机网络 🌹往期回顾🌹:【计算机网络】NAT、代理服务器、内网穿透、内网打洞、局域网中交换机 🔖流水不争&#xff0…

LeetCode--23.合并k个升序链表

解题思路: 1.获取信息: 给出了多个升序链表,要求合并成一个升序链表,返回首元结点 2.分析题目: 外面在21题的时候,讲了怎样合并两个升序链表为一个升序链表,不了解的,建议去看一下21…

【推荐算法】NeuralCF:深度学习重构协同过滤的革命性突破

NeuralCF:深度学习重构协同过滤的革命性突破 一、算法背景知识:协同过滤的演进与局限1.1 协同过滤的发展历程1.2 传统矩阵分解的缺陷 二、算法理论/结构:NeuralCF架构设计2.1 基础NeuralCF结构2.2 双塔模型进阶结构2.3 模型实现流程对比 三、…

负载均衡相关基本概念

负载均衡在系统架构设计中至关重要,其核心目标是合理分配负载,提升系统整体性能和可靠性。本文简要介绍了负载均衡的基本概念,包括四层和七层负载均衡、负载均衡的使用场景和实现方式、负载均衡的常用算法以及一些配置相关知识。 1、负载均衡…

集成电路设计:从概念到实现的完整解析优雅草卓伊凡

集成电路设计:从概念到实现的完整解析优雅草卓伊凡 一、集成电路设计:芯片制造的”灵魂蓝图” 1.1 什么是集成电路设计? 集成电路(IC)设计是指通过电子设计自动化(EDA)工具,将数百…

动态规划之网格图模型(二)

文章目录 动态规划之网格图模型(二)LeetCode 931. 下降路径最小和思路Golang 代码 LeetCode 2684. 矩阵中移动的最大次数思路Golang 代码 LeetCode 2304. 网格中的最小路径代价思路Golang 代码 LeetCode 1289. 下降路径最小和 II思路Golang 代码 LeetCod…

robot_lab——rsl_rl的train.py整体逻辑

文章目录 Go2机器人训练流程详细分析概述1. 训练启动流程1.1 命令行参数解析RSL-RL相关参数组Isaac Sim应用启动参数组 1.2 RL配置1.3 Isaac Sim启动 2. 环境配置加载2.1 Hydra配置系统 3. 环境创建与初始化3.1 Gym环境创建3.2 Manager系统初始化3.2.1 ObservationManager3.2.2…

.NET 原生驾驭 AI 新基建实战系列(三):Chroma ── 轻松构建智能应用的向量数据库

在人工智能AI和机器学习ML迅猛发展的今天,数据的存储和检索需求发生了巨大变化。传统的数据库擅长处理结构化数据,但在面对高维向量数据时往往力不从心。向量数据库作为一种新兴技术,专为AI应用设计,能够高效地存储和查询高维向量…

8.RV1126-OPENCV 视频中添加LOGO

一.视频中添加 LOGO 图像大体流程 首先初始化VI,VENC模块并使能,然后创建两个线程:1.把LOGO灰度化,然后获取VI原始数据,其次把VI数据Mat化并创建一个感兴趣区域,最后把LOGO放感兴趣区域里并把数据发送给VENC。2.专门获…

API管理是什么?API自动化测试怎么搭建?

目录 一、API管理是什么 (一)API管理的定义 (二)API管理的重要性 二、API管理的主要内容 (一)API设计 1. 遵循标准规范 2. 考虑可扩展性 3. 保证接口的易用性 (二)API开发 …

GIC v3 v4 虚拟化架构

ARMV8-A架构中包含了对虚拟化的支持。为了与架构保持匹配,GICV3也对虚拟化做了支持。新增了以下特性: 对CPU interface的硬件虚拟化虚拟中断maintenance 中断:用于通知监管程序(例如hypervisor)一些特定的虚拟机事件 …

2025远离Deno和Fresh

原创作者:庄晓立(LIIGO) 原创时间:2025年6月6日 原创链接:https://blog.csdn.net/liigo/article/details/148479884 版权所有,转载请注明出处! 相识 Deno,是Nodejs原开发者Ryan Da…

Flask+LayUI开发手记(七):头像的上传及突破static目录限制

看了看,上篇开发手记是去年8月份写的,到现在差2个月整一年了。停更这么长时间,第一个原因是中间帮朋友忙一个活,那个技术架构是用springboot的,虽然前端也用layUI,但和Flask-python完全不搭界,所…

MiniExcel模板填充Excel导出

目录 1.官方文档 2. 把要导出的数据new一个匿名对象 3.导出 4.注意事项 5.模板制作 6.结果 1.官方文档 https://gitee.com/dotnetchina/MiniExcel/#%E6%A8%A1%E6%9D%BF%E5%A1%AB%E5%85%85-excel // 1. By POCO var value new {Name "Jack",CreateDate n…

MCP协议重构AI Agent生态:万能插槽如何终结工具孤岛?

前言 在人工智能技术快速发展的2025年,MCP(Model Context Protocol,模型上下文协议)正逐渐成为AI Agent生态系统的关键基础设施。这一由Anthropic主导的开放协议,旨在解决AI模型与外部工具和数据源之间的连接难题,被业界形象地称…

阿里云事件总线 EventBridge 正式商业化,构建智能化时代的企业级云上事件枢纽

作者:肯梦、稚柳 产品演进历程:在技术浪潮中的成长之路 早在 2018 年,Gartner 评估报告便将事件驱动模型(Event-Driven Model)列为十大战略技术趋势之一,指出事件驱动架构(EDA,Eve…