迭代实现 斐波那契数列

1斐波那契数列的定义

斐波那契数列(Fibonacci sequence),又称黄金分割数列,是由意大利数学家莱昂纳多·斐波那契(Leonardo Fibonacci)在1202年提出的。其核心定义为:

  1. 首项(第1项)和第2项均为1;

  2. 从第3项开始,每一项都等于它前两项的和。

用数学公式可表示为:

F(1) = 1,F(2) = 1

F(n) = F(n-1) + F(n-2) (其中n ≥ 3,n为正整数)

根据定义,斐波那契数列的前10项为:1, 1, 2, 3, 5, 8, 13, 21, 34, 55...

2 迭代实现

思路:通过循环迭代,用变量保存前两项的值,依次计算出当前项,避免重复计算,效率大幅提升。

cpp 复制代码
//迭代实现斐波那契数列
#include <stdio.h>
int fib(int n)
{

	int a = 1;
	int b = 1;
	int c = 1;
	while (n >= 3)
	{
	    c = a + b;
		a = b;
		b = c;
		n--;
	}
	return c;
}
int main()
{
	int n = 0;
	scanf("%d", &n);
	int b = fib(n);
	printf("%d", b);
	return 0;
}

3 递归实现

cpp 复制代码
#include <stdio.h>

// 递归实现斐波那契数列
int fib_recursion(int n) {
    // 边界条件:处理n≤0的非法输入
    if (n <= 0) {
        printf("输入错误,n必须为正整数!\n");
        return -1;
    }
    // 递归终止条件:第1项和第2项均为1
    if (n == 1 || n == 2) {
        return 1;
    }
    // 递归公式:F(n) = F(n-1) + F(n-2)
    return fib_recursion(n - 1) + fib_recursion(n - 2);
}

int main() {
    int n = 0;
    printf("请输入要计算的斐波那契数列项数:");
    scanf("%d", &n);
    
    int result = fib_recursion(n);
    if (result != -1) {
        printf("斐波那契数列第%d项是:%d\n", n, result);
    }
    return 0;
}

优缺点:

优点:代码简洁直观,直接映射数学定义,易于理解;

缺点:效率极低,存在大量重复计算(例如计算F(5)时,会重复计算F(3)、F(2)等),当n较大(如n>30)时,运行时间会显著增加,甚至出现卡顿。

3 用尾递归怎样实现

先理解:什么是尾递归?

尾递归是递归的一种特殊形式:

  • 普通递归:函数最后一步是调用自身 + 其他运算 (比如 return fib(n-1) + fib(n-2)),会产生大量重复计算,且需要保存多层调用栈。
  • 尾递归:函数最后一步只有自身调用,没有额外运算,编译器 / 解释器可优化为迭代(复用栈帧),效率和迭代几乎一致。

实现尾递归的关键:用参数保存中间结果,而非在递归返回后做加法运算。

cpp 复制代码
#include <stdio.h>

// 核心尾递归函数(辅助函数)
// a: 保存前前项(初始为第1项 1)
// b: 保存前一项(初始为第2项 1)
// n: 剩余需要计算的项数
int fib_tail_recursion_helper(int a, int b, int n) {
    // 递归终止条件:剩余项数为0,返回当前的前一项(即目标项)
    if (n == 0) {
        return a;
    }
    // 尾递归调用:仅更新参数,无额外运算
    // a 变为原b,b 变为 a+b(当前项),剩余项数n-1
    return fib_tail_recursion_helper(b, a + b, n - 1);
}

// 对外暴露的函数(封装尾递归,简化调用)
int fib_tail_recursion(int n) {
    // 1. 处理非法输入
    if (n <= 0) {
        printf("输入错误!n必须是正整数\n");
        return -1;
    }
    // 2. 边界条件:第1、2项直接返回1
    if (n == 1 || n == 2) {
        return 1;
    }
    // 3. 调用尾递归辅助函数(初始参数适配n≥3的情况)
    // 初始a=1(第1项)、b=1(第2项),剩余计算n-2项(因为前2项已确定)
    return fib_tail_recursion_helper(1, 1, n - 2);
}

// 主函数测试
int main() {
    int n = 0;
    printf("请输入要计算的斐波那契数列项数:");
    scanf("%d", &n);
    
    int result = fib_tail_recursion(n);
    if (result != -1) {
        printf("斐波那契数列第%d项是:%d\n", n, result);
    }
    return 0;
}
相关推荐
Omics Pro5 小时前
Arc研究所Cell|全新虚拟细胞官方基准评测框架
大数据·人工智能·深度学习·算法·机器学习
白狐_7985 小时前
408 数据结构|红黑树插入:只记两大类
数据结构
CoderYanger7 小时前
A.每日一题:1140. 石子游戏 II
java·程序人生·算法·leetcode·游戏·职场和发展·深度优先
小雨笙笙7 小时前
机器学习:评估模型与选择
人工智能·算法·机器学习
高亦真7 小时前
今天是学习嵌入式的第35天
linux·学习·算法
HugoStudio_SWAN7 小时前
洛谷 P1319 / P1320 压缩技术——同一枚硬币的正反面
c++·学习·程序人生·算法
wdfk_prog9 小时前
canopennode-rtt推荐,不只可以做从站,也可以承担主站角色
c语言·开发语言·数据库·学习·算法·深度优先
BioRunYiXue9 小时前
科研干货 | IC50全面解读:概念解析、实验设计与数据分析要点
java·开发语言·javascript·人工智能·算法·数据挖掘·数据分析
hahaha60169 小时前
HLS高层次综合设计技巧--UART_TX接收模块设计案例
人工智能·算法·计算机视觉
302wanger9 小时前
一个程序员看完《逆行人生》:电影没说透的,比电影更扎心
算法