斐波那契数列---递归和递归优化

斐波那契数列:

       经典数学问题之一;斐波那契数列,又称黄金分割数列,指的是这样一个数列:

  1、1、2、3、5、8、13、21、……

想必看到这个数列大家很容易的就推算出来后面好几项的值,那么到底有什么规律,简单说,就是前两项的和是第三项的值,也许你会想到的是迭代,也学你想到的是递归。

   简单分析一下递归:

int fibon(int n)
{
	n1 ++;
	if(n <= 2)//递归出口
	{
		return 1;
	}
	return fibon(n-1) + fibon(n-2);
}
这就是简单的递归,咋先分析一下,若此时你给的n为5,直接到了递归这块,那么画个图分析一下,普通的递归:



怎样优化,很简单那么你如果吧已经算过的值,保存起来下次直接用的话,会不会就递归次数明显减少了。好了下面就有两个代码,一个是非优化,一个是优化的。

#include<stdio.h>

int n1 = 0;//记录普通的递归次数
int n2 = 0;//优化的递归次数

//普通递归函数
int fibon(int n)
{
	n1 ++;
	if(n <= 2)//递归出口
	{
		return 1;
	}
	return fibon(n-1) + fibon(n-2);
}
//优化后的递归函数
int fibonac(int a,int b,int n)
{
	n2 ++;
	if(n > 2)
	{
		return fibonac(a+b,a,n-1);
	}
	return a;
}
int main()
{
	int n = 10;//第几个斐波那契数列
	int a = 1; //斐波那契数列的第一项
	int b = 1;//第二项
	int i = fibon(n);//普通的递归
	int j = fibonac(a,b,n);//优化后的递归
	printf("第n个fibon数是--%d\n",i);
	printf("次数--%d\n",n1);
	printf("第n个fibon数是--%d\n",j);
	printf("次数--%d\n",n2);
	return 0;
}

ok!


看看结果不难发现优化的好处了吧!







  • 23
    点赞
  • 75
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
以下是一个优化后的RISC-V递归斐波那契数列的代码: ``` .global main .data fib1: .word 1 fib2: .word 1 n: .word 10 .text main: lw a0, n # 加载n的值 addi sp, sp, -16 # 分配栈空间 sw ra, 12(sp) # 保存返回地址 sw s0, 8(sp) # 保存s0的值 addi s0, sp, 16 # 设置s0的值为栈顶地址 jal fib # 调用递归函数 lw ra, 12(sp) # 恢复返回地址 lw s0, 8(sp) # 恢复s0的值 addi sp, sp, 16 # 释放栈空间 li a7, 10 # 系统调用退出程序 ecall fib: addi sp, sp, -16 # 分配栈空间 sw ra, 12(sp) # 保存返回地址 sw s0, 8(sp) # 保存s0的值 sw a0, 0(sp) # 保存参数n的值 addi s0, sp, 16 # 设置s0的值为栈顶地址 lw a0, 0(sp) # 加载参数n的值 li a1, 2 # 设置常数2 blt a0, a1, base # n < 2,直接返回1 addi a0, a0, -1 # 调用递归函数计算fib(n-1) jal fib sw a0, -4(s0) # 保存fib(n-1)的结果 addi a0, a0, -2 # 调用递归函数计算fib(n-2) jal fib lw a1, -4(s0) # 加载fib(n-1)的结果 add a0, a1, a0 # 计算fib(n)的结果 lw ra, 12(sp) # 恢复返回地址 lw s0, 8(sp) # 恢复s0的值 lw a0, 0(sp) # 恢复参数n的值 addi sp, sp, 16 # 释放栈空间 jr ra base: li a0, 1 # n < 2,返回1 j end end: jr ra ``` 这个代码使用了栈来保存递归函数的返回地址和s0寄存器的值。在每次递归调用之前,它会将这些值保存在栈上,并在递归完成后恢复它们。这样可以确保每次递归调用都有自己的返回地址和s0寄存器的值。 此外,该代码还使用了一个基本情况来处理n < 2的情况,这样就可以避免无限递归的问题。如果n < 2,则直接返回1。 最后,该代码还将fib(n-1)的结果保存在栈上,以便在计算fib(n)时可以直接使用。这样可以避免重复计算fib(n-1)的问题。 综上所述,这个代码使用了栈来保存状态,处理了基本情况,并避免了重复计算的问题,从而优化递归斐波那契数列的性能。
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值