递归和尾递归(用C语言解斐波那契和阶乘问题)

很多人都对递归有了解,但是为尾递归很少,所以这次来专门讲一讲关于尾递归的一些问题。

什么是尾递归

如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。因为在一些题目的做法中,我们可以发现递归的使用有局限性,有时候会占用相当大的空间。比如斐波那契问题,代码很容易用递归去写,但是浪费了大量的内存,一个数会重复计算多次,所以我们来使用尾递归。这里引用一个我看别人说的一句话,我认为非常对普通递归的结果是返回值,尾递归的结果是参数。完全可以这样理解。

尾递归的优化原理

尾递归优化的概念 尾递归是指递归调用出现在函数体的最后,并且是返回值的一部分。 它是一种特殊的递归形式,不会在回归过程中做其他操作或表达式的计算。尾调用优化 尾调用是尾递归优化的基础。 尾调用是指函数调用出现在调用者函数的最后,并且该调用的返回值直接被当前函数返回。 尾调用优化的目的是将递归调用转化为尾调用,从而减少函数调用栈的使用。 通过尾调用优化,实现函数的尾递归优化,可以避免递归调用带来的栈溢出问题。

举例子来说明一下:

阶乘问题(源码一律放后面)

求一个数的阶乘,普通求法非常简单不讲。

首先设置一个函数,你用函数传参的性质,建立出这个阶乘的函数模型,当X等于零的时候那么就直接返回一,也就是结束标志,若X没有为零的时候就进行递归操作

那么尾递归是怎么实现的呢?

注意之前说的一句话,普通递归的结果是返回值,尾递归的结果是参数,所以为递归和尾递归的一个区别是为地规会多一个参数,将这个函数不变,但是多传一个变量,那么我们就想办法让最后的机会用这个变量表示出来,所以说当n等于1的时候我们直接返回那个变量,否则就继续往下传参,我们将参数一一对应,这里面用逗号表达式的知识,这个变量随着n减减下来最后会等于1也就是说,这个函数的结果就是最后ret的那个值,就是阶乘。

斐波那契问题(源码一律放后面)

什么是斐波那契数?

指的是这样的一个数列:1、1、2、3、5、8、13、21、34、……,这个数列从第 3 项开始,每一项都等于前面两项之和。

做法

递归太简单直接摆

普通做法

利用一个前面加后面一直往后推的一个思想,把加的值,慢慢传递,最开始都是从一n大于二的时候意思就是说从第三个数开始,把第三个数等于前两个数相加,第二个数传给第一个数第三个数再传给第二个数以此类推,最后再返回第三个数就可以了。

尾递归

这里跟普通的相比也是多传两个参数,因为最开始的两个数都是一,我们必须提前知道,其实做法和普通方法的思维是一致的也是相加,但是最后需要用这个b来表示出来,用逗号表达式的这个知识和函数传参

源码

阶乘:

//int test(int x)
//{
//    if (x == 0)
//    {
//        return 1;
//    }
//    return x * test(x - 1);
//
//}
//int main()
//{
//    int n = 0;
//    scanf_s("%d", &n);
//    int a = test(n);
//    printf("%d", a);
//
//    return 0;
//}
//int main()
//{
//    int n = 0;
//    scanf_s("%d", &n);//n=4
//    int sum = 1;
//    for (int i = 1; i<=n; i++)
//    {
//        sum = sum * i;
//    }
//
//    printf("%d", sum);
//
//    return 0;
//}

//int wei(int n, int ret)
//{
//     if (n == 0)
//        return 1;
//    else if (n == 1)
//        return ret;
//    else
//        return wei(n - 1, n * ret);
//}

斐波那契:

int Fib(int n, int a, int b) 
{
    if (n < 3)
    {
        return b;
    }
    else
        return Fib(n - 1, b, a + b);
}

int main()
{
    int n = 0;
    int ret = 0;
    scanf_s("%d", &n);
    ret = Fid(n,1,1);
    printf("%d\n", ret);
    return 0;

    return 0;
}

//int Fid(int n)
//{
//    if (n <= 2)
//        return 1;
//    else
//        return Fid(n - 1) + Fid(n - 2);
//}

//int Fid(int n)
//{
//    int a, b, c = 1;
//    while (n > 2)
//    {
//        c = a + b;
//        a = b;
//        b = c;
//        n--;
//    }
//    return c;
//}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

uniapp scroll-view用法[下拉刷新,触底事件等等...](4)

前言:可滚动视图区域。用于区域滚动 话不多说 直接上官网属性 官网示例 讲一下常用的几个 scroll 滚动时触发 scrolltoupper 滚动到顶部或左边&#xff0c;会触发 scrolltoupper 事件 scrolltolower 滚动到底部或右边&#xff0c;会触发 scrolltolower 事件 1.纵向滚动…

面向对象、封装、继承、多态、JavaBean

二、面向对象 什么是对象 什么是对象&#xff1f;之前我们讲过&#xff0c;对象就是计算机中的虚拟物体。例如 System.out&#xff0c;System.in 等等。然而&#xff0c;要开发自己的应用程序&#xff0c;只有这些现成的对象还远远不够。需要我们自己来创建新的对象。 1. 抽…

fpga外置flash程序烧录流程

Fpga外置FLASH程序烧录流程&#xff1a; step1&#xff1a; 打开vivado2019.2软件&#xff0c;找到hardware manager选项&#xff0c;进入该功能界面&#xff1b; Step2&#xff1a; 确定连接状态&#xff0c;当JTAG正确连接到板卡的调试插针后&#xff0c;会在状态窗口显示…

【嵌入式学习】网络通信基础-项目篇:简单UDP聊天室

源码已在GitHub开源&#xff1a;0clock/LearnEmbed-projects/chat 实现的功能 客户端功能&#xff1a; 上线发送登录的用户名[yes] 发送消息和接收消息[yes] quit退出 服务器端功能&#xff1a; 统计用户上线信息&#xff0c;放入链表中[yes] 接收用户信息并给其他用户发送消…

模型选择实战

我们现在可以通过多项式拟合来探索这些概念。 import math import numpy as np import torch from torch import nn from d2l import torch as d2l生成数据集 给定x&#xff0c;我们将使用以下三阶多项式来生成训练和测试数据的标签&#xff1a; max_degree 20 # 多项式的最…

Redis中BigKey的分析与优化

Redis中BigKey的分析与优化 Redis以其出色的性能和易用性&#xff0c;在互联网技术栈中占据了重要的地位。 但是&#xff0c;高效的工具使用不当也会成为性能瓶颈。在Redis中&#xff0c;BigKey是常见的性能杀手之一&#xff0c;它们会消耗过多的内存&#xff0c;导致网络拥塞…

4 课程分类查询

4 课程分类查询 4.1 需求分析 下边根据内容管理模块的业务流程&#xff0c;下一步要实现新增课程&#xff0c;在新增课程界面&#xff0c;有三处信息需要选择&#xff0c;如下图&#xff1a; 课程等级、课程类型来源于数据字典表&#xff0c;此部分的信息前端已从系统管理服…

将vue组件发布成npm包

文章目录 前言一、环境准备1.首先最基本的需要安装nodejs&#xff0c;版本推荐 v10 以上&#xff0c;因为需要安装vue-cli2.安装vue-cli 二、初始化项目1.构建项目2.开发组件/加入组件3. 修改配置文件 三、调试1、执行打包命令2、发布本地连接包3、测试项目 四、发布使用1、注册…

从零开始训练 YOLOv8最新8.1版本教程说明(包含Mac、Windows、Linux端 )同之前的项目版本代码有区别

从零开始训练 YOLOv8 - 最新8.1版本教程说明 本文适用Windows/Linux/Mac:从零开始使用Windows/Linux/Mac训练 YOLOv8 算法项目 《芒果 YOLOv8 目标检测算法 改进》 适用于芒果专栏改进 YOLOv8 算法 文章目录 官方 YOLOv8 算法介绍改进网络代码汇总第一步 配置环境1.1 系列配…

【GitHub项目推荐--不错的 Go 学习项目】【转载】

开源实时性能分析平台 Pyroscope 是基于 Go 的开源实时性能分析平台&#xff0c;在源码中添加几行代码 pyroscope 就能帮你找出源代码中的性能问题和瓶颈、CPU 利用率过高的原因&#xff0c;调用树展示帮助你理解程序&#xff0c;支持 Go、Python、Ruby 语言。 Pyroscope 可以…

力(FFT,acwing2313)

题目路径&#xff1a; https://www.acwing.com/problem/content/2315/ 思路&#xff1a;

css实现右边边框分割线 渐变色,边框四角样式

分割线 代码 .data-item:first-of-type {border-right: 2px solid;border-image: linear-gradient(to top,rgba(0, 0, 0, 0.1) 0%,rgba(81, 110, 197, 0.76) 50%,rgba(0, 0, 0, 0.1) 100%)1;padding: 15px 0;}四角边框样式 代码 .chart-box {cursor: pointer;background: line…

[docker] Docker 网络

一、Docker 网络 1.1 Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认…

axi_quad_spi

文章目录 系统框图正常模式XIP模式 性能IP 核配置AXI Interface OptionXIP ModePerformance Mode SPI OptionsModeTransaction WidthFrequency RatioSlave DeviceEnable Master ModeEnable STARTUP Primitive 寄存器映射0x40 (SRR) 软件复位0x60 (SPICR) SPI控制0x64 (SPISR) S…

Docker安装Clickhouse详细教程

简介 ClickHouse是一种列式数据库管理系统&#xff0c;专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统&#xff0c;最初由俄罗斯搜索引擎公司Yandex开发&#xff0c;用于满足大规模数据分析和报告的需求。 特点 开源的列式存储数据库管理系统&#xff0c;…

C# 将HTML网页、HTML字符串转换为PDF文件

将HTML转换为PDF可实现格式保留、可靠打印、文档归档等多种用途&#xff0c;满足不同领域和情境下的需求。本文将通过以下两个示例&#xff0c;演示如何使用第三方库Spire.PDF for .NET和QT插件在C# 中将Html 网页&#xff08;URL&#xff09;或HTML字符串转为PDF文件。 HTML转…

ubuntu20根目录扩容

ubuntu根目录/ 或者 /home文件夹有时出现空间满了的情况&#xff0c;可以用gparted工具进行空间的重新分配。 首先&#xff0c;如果你是双系统&#xff0c;需要从windows系统下磁盘压缩分配一部分未使用的空间给ubuntu&#xff0c;注意压缩的空间要邻接ubuntu所在盘的位置。 …

NTFS 磁盘管理 :NTFS Disk by Omi NTFS

NTFS Disk by Omi NTFS是一款专为Mac系统设计的NTFS文件系统读写解决方案的工具。它可以帮助Mac用户方便地访问和管理NTFS格式的硬盘、U盘、移动硬盘以及其他存储设备&#xff0c;提供高效稳定的NTFS卷管理功能。 NTFS 磁盘管理 &#xff1a;NTFS Disk by Omi NTFS 该软件的主…

C#调用SqlSugar操作达梦数据库报错“无效的表或视图名”

安装达梦数据库后&#xff0c;使用SqlSugar连接测试数据库并基于DBFirst方式创建数据库表对应的类&#xff0c;主要代码如下&#xff1a; SqlSugarClient db new SqlSugarClient(new ConnectionConfig(){DbType DbType.Dm,ConnectionString "Serverlocalhost; User Id…

仓储管理系统——软件工程报告(项目管理)⑦

项目管理 一、管理计划 这个项目的计划是一个关键的阶段&#xff0c;它需要考虑到多个因素&#xff0c;包括软件规模的度量、工作量的估算以及详细的进度计划&#xff0c;以确保项目按时、高质量地完成。 软件规模度量&#xff1a; 在软件工程中&#xff0c;度量软件规模是…