迭代实现 斐波那契数列

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;
}
相关推荐
珂朵莉MM21 小时前
全球校园人工智能算法精英大赛-产业命题赛-算法巅峰赛 2025年度画像
java·人工智能·算法·机器人
Morwit21 小时前
*【力扣hot100】 647. 回文子串
c++·算法·leetcode
DonnyCoy21 小时前
Android性能之数据结构
数据结构
天赐学c语言21 小时前
1.7 - 删除排序链表中的重要元素II && 哈希冲突常用解决冲突方法
数据结构·c++·链表·哈希算法·leecode
tobias.b21 小时前
408真题解析-2009-13-计组-浮点数加减运算
算法·计算机考研·408考研·408真题
菜鸟233号1 天前
力扣96 不同的二叉搜索树 java实现
java·数据结构·算法·leetcode
Coovally AI模型快速验证1 天前
超越Sora的开源思路:如何用预训练组件高效训练你的视频扩散模型?(附训练代码)
人工智能·算法·yolo·计算机视觉·音视频·无人机
千金裘换酒1 天前
Leetcode 有效括号 栈
算法·leetcode·职场和发展
空空潍1 天前
hot100-最小覆盖字串(day12)
数据结构·算法·leetcode