Go语言比较递归和循环执行效率

一、概念

1.递归

递归是指一个函数在其定义中直接或间接调用自身的编程方法 。简单来说,就是函数自己调用自己。递归主要用于将复杂的问题分解为较小的、相同类型的子问题,通过不断缩小问题的规模,直到遇到一个最简单、最基础的情况(基本情况),从而停止递归。
递归算法有两个过程,一是递推过程,二是回归的过程。

2.循环

循环是计算机科学运算领域的用语,也是一种常见的控制流程。循环是一段在程序中只出现一次,但可能会连续运行多次的代码。循环中的代码会运行特定的次数,或者是运行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都运行一次。

二、执行过程

1.递归

在支持自调用的编程语言中,递归可以通过简单的函数调用来完成,如计算阶乘的程序在数学上可以定义为:
在这里插入图片描述
递归程序执行过程可分解为下图
在这里插入图片描述

2.循环

循环开始前需要初始化变量,然后进入表达式做判断,判断为true,执行循环体,判断为false则退出循环,输出结果
循环程序执行过程可分解为下图:
在这里插入图片描述

三、代码示例

1.go语言代码示例

package mainimport ("fmt""time"
)// 直接递归调用,求n的阶乘
// 参数:
//
//	n - 一个正整数,表示需要计算阶乘的数字。
//
// 返回值:
//
// result - n 的阶乘结果。
func recursion(n int) (result int) {if n >= 1 {// 直接递归调用函数result = n * recursion(n-1)return result}return 1
}// loop 计算给定数字的阶乘。
// 参数:
//
//	n - 一个正整数,表示需要计算阶乘的数字。
//
// 返回值:
//
//	result - n 的阶乘结果。
func loop(n int) (result int) {// 当n < 0时,程序panic退出if n <= 0 {panic("Input must be a non-negative integer")}// 初始化 y 为 1,作为阶乘计算的起始值。y := 1// 从 1 循环到 n,逐步计算阶乘。for i := 1; i <= n; i++ {// 在每次循环中,将当前数字 i 与 y 相乘,累积阶乘结果。y *= i}// 返回计算得到的阶乘结果。return y
}func main() {// 初始化变量x为10,用于后续的递归和循环计算。x := 5// 开始递归计算,并记录开始时间。startRecurison := time.Now()// 打印递归计算的开始时间、结果以及花费的时间。fmt.Printf("recurison start time:%v, result:%d\n", startRecurison, recursion(x))fmt.Println("elapse time:", time.Since(startRecurison))// 开始循环计算,并记录开始时间。startLoop := time.Now()// 打印循环计算的开始时间、结果以及花费的时间。fmt.Printf("loop start time:%v, result:%d\n", startLoop, loop(x))fmt.Println("elapse time:", time.Since(startLoop))// 比较递归和循环的执行时间,判断哪个更快。if time.Since(startRecurison) > time.Since(startLoop) {fmt.Println("loop algorithm is faster")} else {fmt.Println("recursion algorithm is faster")}
}

2.查看执行结果

最终比较结果:循环算法的执行效率更好,速度更快

PS D:\Project\GoWorkSpace\DataStructure\0408> go run .\Recursion.go
recurison start time:2025-04-09 10:49:17.117547 +0800 CST m=+0.005692801, result:120
elapse time: 2.9766ms
loop start time:2025-04-09 10:49:17.1205236 +0800 CST m=+0.008669401, result:120
elapse time: 533.2µs
loop algorithm is faster

四、总结

1.递归和循环的区别

1.1内存占用

递归:每次调用都会在调用栈中保存当前状态,深度递归可能导致栈溢出(如 n=10000 时计算阶乘)。
循环:通常只占用常量内存(如几个变量)。

1.2效率

递归:函数调用需要额外开销(保存上下文、参数传递等),但某些语言支持尾递归优化(如 Scheme),可减少开销。
循环:通常更高效,无函数调用开销。

1.3可读性

递归:更符合分治、树遍历等问题的数学定义(如斐波那契数列、汉诺塔)。
循环:适合简单重复任务(如遍历数组)。

1.4典型场景

递归:分治算法(快速排序)、树/图遍历(DFS)、动态规划问题。
循环:线性操作(如求和、遍历)、需要严格控制资源时。

1.5转换与限制
  • 相互转换
    任何递归问题都可以用循环(+栈结构)实现,反之亦然,但代码复杂度可能变化。
  • 限制
    递归:受编程语言的调用栈深度限制。
    循环:需手动管理状态,复杂逻辑可能使代码臃肿。
1.6总结表格
递归循环
实现方式函数自我调用显式迭代(for/while)
内存占用高(栈帧累积)低(常量空间)
性能可能因调用开销较慢通常更高效
可读性适合分治、树结构问题简单直观
适用场景分治、回溯、数学递归问题线性操作、资源敏感任务

2.场景选择

用递归:问题本身是递归结构、代码简洁性优先(如树的遍历)
用循环:追求性能、处理大数据量、避免栈溢出风险。

概念补充
递归展开:指通过逐步展示递归函数的调用过程,将递归的每一层执行细节明确呈现出来,以直观理解递归如何分解问题、传递参数、返回结果。这一过程常用于分析递归逻辑、调试代码或手动模拟递归行为。
如果出现递归算法栈溢出,用循环算法优化也是一种方法

如有疏漏,欢迎评论区留言

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

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

相关文章

keepalived高可用介绍

keepalived 是 Linux 一个轻量级的高可用解决方案&#xff0c;提供了心跳检测和资源接管、检测集群中的系统服务&#xff0c;在集群节点间转移共享IP 地址的所有者等。 工作原理 keepalived 通过 VRRP&#xff08;virtual router redundancy protocol&#xff09;虚拟路由冗余…

数据分享:汽车测评数据

说明&#xff1a;如需数据可以直接到文章最后关注获取。 1.数据背景 Car Evaluation汽车测评数据集是一个经典的机器学习数据集&#xff0c;最初由 Marko Bohanec 和 Blaz Zupan 创建&#xff0c;并在 1997 年发表于论文 "Classifier learning from examples: Common …

NLP简介及其发展历史

自然语言处理&#xff08;Natural Language Processing&#xff0c;简称NLP&#xff09;是人工智能和计算机科学领域中的一个重要分支&#xff0c;致力于实现人与计算机之间自然、高效的语言交流。本文将介绍NLP的基本概念以及其发展历史。 一、什么是自然语言处理&#xff1f…

HOOPS Visualize:跨平台、高性能的三维图形渲染技术解析

在当今数字化时代&#xff0c;三维可视化技术已成为众多行业的核心竞争力。HOOPS Visualize作为一款功能强大的三维图形渲染引擎&#xff0c;凭借其卓越的渲染能力、跨平台支持、丰富的交互功能、高度定制化以及快速部署等特性&#xff0c;为开发人员提供了构建高质量、高性能3…

蓝桥杯速成刷题清单(上)

一、1.排序 - 蓝桥云课 &#xff08;快速排序&#xff09;算法代码&#xff1a; #include <bits/stdc.h> using namespace std; const int N 5e5 10; int a[N];int main() {int n;cin >> n;for (int i 0; i < n; i) {cin >> a[i];}sort(a, a n);for …

Java面试黄金宝典44

1. 查看进程的运行堆栈信息命令 gstack gstack 是 Linux 系统下用于查看指定进程运行时堆栈信息的工具。当程序出现崩溃、死锁或者性能瓶颈等问题时,借助 gstack 可以查看进程中各个线程的调用栈,从而辅助开发人员定位问题。 定义 gstack 本质上是一个封装了底层 ptrace 系统…

嵌入式硬件篇---TOF陀螺仪SPI液晶屏

文章目录 前言1. TOF传感器&#xff08;Time of Flight&#xff09;原理STM32使用方法硬件连接SDASCLVCC\GND 软件配置初始化I2C外设库函数驱动&#xff1a;读取数据 2. 陀螺仪&#xff08;如MPU6050&#xff09;原理STM32使用方法硬件连接SDA/SCLINTVCC/GND 软件配置初始化I2C…

【scikit-learn基础】--『预处理』之 正则化

数据的预处理是数据分析&#xff0c;或者机器学习训练前的重要步骤。 通过数据预处理&#xff0c;可以 提高数据质量&#xff0c;处理数据的缺失值、异常值和重复值等问题&#xff0c;增加数据的准确性和可靠性整合不同数据&#xff0c;数据的来源和结构可能多种多样&#xff…

LeetCode Hot100 刷题笔记(2)—— 子串、普通数组、矩阵

目录 前言 一、子串 1. 和为 K 的子数组 2. 滑动窗口最大值 3. 最小覆盖子串 二、普通数组 4. 最大子数组和 5. 合并区间 6. 轮转数组 7. 除自身以外数组的乘积 8. 缺失的第一个正数 三、矩阵 9. 矩阵置零 10. 螺旋矩阵 11. 旋转图像 12. 搜索二维矩阵 II 前言 一、子串&#…

【Git 常用操作指令指南】

一、初始化与配置 1. 设置全局账户信息 git config --global user.name "用户名" # 设置全局用户名 git config --global user.email "邮箱" # 设置全局邮箱 --global 表示全局生效&#xff0c;若需针对单个仓库配置&#xff0c;可省略该参数 2.…

教培行业创建自己品牌的重要意义——教育培训小程序

在竞争激烈的教培行业&#xff0c;创建自身品牌意义重大。 拥有独特品牌能显著提升机构竞争力与辨识度。如今教培市场同质化严重&#xff0c;一个亮眼的品牌小程序可使机构从众多竞争者中脱颖而出&#xff0c;让学员和家长快速识别并记住。 品牌小程序有助于增强信任度和口碑。…

Docker 介绍 · 安装详细教程

为什么选择 Docker&#xff1f; ✅ 环境一致性 – 告别“在我机器上能跑”的问题&#xff0c;确保开发、测试、生产环境一致。 ✅ 高效轻量 – 秒级启动&#xff0c;资源占用远低于传统虚拟机。 ✅ 跨平台支持 – 可在任何支持 Docker 的环境中运行&#xff0c;包括云服务器、…

GitHub 上开源一个小项目的完整指南

GitHub 上开源一个小项目的完整指南 &#x1f680; 第一步&#xff1a;准备你的项目 在开源之前&#xff0c;确保项目是可用且有一定结构的&#xff1a; ✅ 最低要求 项目文件清晰、结构合理&#xff08;比如&#xff1a;src/、README.md、LICENSE&#xff09;项目能在本地正…

React 第三十节 使用 useState 和 useEffect Hook实现购物车

不使用 redux 实现 购物车案例 使用 React 自带的 useState 和 useEffect Hook 即可实现购物车 export default function ShoppingCar() {// 要结算的商品 总数 以及总价const [totalNum, setTotalNum] useState(0)const [totalPerice, setTotalPerice] useState(0)// 商品…

蓝桥杯第十一届省赛C++B组真题解析

蓝桥杯第十一届省赛CB组真题解析 八、回文日期https://www.lanqiao.cn/problems/348/learning 方法一&#xff1a;暴力枚举所有的日期&#xff0c;记录有多少个回文日期。 #include <bits/stdc.h> using namespace std; int month[13]{0,31,28,31,30,31,30,31,31,30,31…

Python和MicroPython的解释器区别

Python和MicroPython的解释器不是同一个&#xff0c;它们在设计目标、实现方式和运行环境上都有显著的区别。以下是它们的主要区别&#xff1a; 1. 底层实现 Python解释器&#xff08;CPython&#xff09;&#xff1a; Python的标准解释器是CPython&#xff08;C语言实现的Pyt…

Cython加密多层目录中的Python脚本方案

近期有一个VueJavaDocker项目中需要加密Python脚本的需求&#xff0c;调研后决定采用Cython。 使用Cython编译为二进制 步骤&#xff1a; 安装Cython&#xff1a;pip install cython创建setup.py&#xff1a; from distutils.core import setup from Cython.Build import c…

力扣DAY40-45 | 热100 | 二叉树:直径、层次遍历、有序数组->二叉搜索树、验证二叉搜索树、二叉搜索树中第K小的元素、右视图

前言 简单、中等 √ 好久没更了&#xff0c;感觉二叉树来回就那些。有点变懒要警醒&#xff0c;不能止步于笨方法&#xff01;&#xff01; 二叉树的直径 我的题解 遍历每个节点&#xff0c;左节点最大深度右节点最大深度当前节点当前节点为中心的直径。如果左节点深度更大…

头歌数据库【数据库概论】第10-11章 故障恢复与并发控制

第1关&#xff1a;数据库恢复技术 1、事务的&#xff08; A&#xff09;特性要求事务必须被视为一个不可分割的最小工作单元 A、原子性 B、一致性 C、隔离性 D、持久性 2、事务的&#xff08;C &#xff09;特性要求一个事务在执行时&#xff0c;不会受到其他事务的影响。 A、原…

windows下,cursor连接MCP服务器

1.下载并安装node 安装后&#xff0c;在cmd命令框中&#xff0c;输入命令node -v可以打印版本号&#xff0c;证明安装完成 2.下载MCP服务器项目 在MCP服务器找到对应项目&#xff0c;这里以server-sequential-thinking为例子 在本地cmd命令窗口&#xff0c;使用下面命令下载…