实现递归与迭代斐波那契数列的算法并画出程序执行时间与n的关系。

递归代码:

// 递归实现斐波那契数列
int fun1(int n) {
    if (n == 0 or n == 1) {
        return 1;
    }
    return fun1(n - 1) + fun1(n - 2);
}

递归结果(部分):

迭代代码:

// 迭代实现斐波那契数列
int fun2(int f[], int n) {
    int i;
    f[0] = 1;
    f[1] = 1;
    for (i = 2; i <= n; i++) {
        f[i] = f[i - 1] + f[i - 2];
    }
    return f[n];
}

迭代结果(部分):

源码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 递归实现斐波那契数列
int fun1(int n) {
    if (n == 0 or n == 1) {
        return 1;
    }
    return fun1(n - 1) + fun1(n - 2);
}

// 迭代实现斐波那契数列
int fun2(int f[], int n) {
    int i;
    f[0] = 1;
    f[1] = 1;
    for (i = 2; i <= n; i++) {
        f[i] = f[i - 1] + f[i - 2];
    }
    return f[n];
}

int main() {
    int n = 50;
    int* f = (int*)malloc((n + 1) * sizeof(int));
    clock_t start, end;
    double time;

    // 测试递归实现斐波那契数列的运行时间
    printf("递归 实现斐波那契数列的运行时间:\n");
    for (int i = 0; i <= n; i++) {
        start = clock();
        int result = fun1(i);
        end = clock();
        time = ((double)(end - start)) / CLOCKS_PER_SEC;//clock()函数返回的时钟计时单元数除以CLOCKS_PER_SEC可以得到以秒为单位的时间
        printf("第%d个数: %d (消耗时间: %f秒)\n", i, result, time);
    }

    printf("\n");

    // 测试迭代实现斐波那契数列的运行时间
    printf("迭代 实现斐波那契数列的运行时间:\n");
    for (int i = 0; i <= n; i++) {
        start = clock();
        int result = fun2(f, i);
        end = clock();
        time = ((double)(end - start)) / CLOCKS_PER_SEC;
        printf("第%d个数: %d (消耗时间: %f秒)\n", i, result, time);
    }

    free(f); // 释放动态分配的内存

    return 0;
}

递归和迭代时间效率对比:

实验结果:由运行结果可视化分析可以得出,当n逐渐增大后,递归所花费的时间明显高于迭代的时间。

原因分析:

  1. 递归:

递归实现斐波那契数列的算法在计算过程中会重复计算很多次相同的子问题,导致时间复杂度高。

在递归实现中,每次递归调用时都会产生两个子问题,直到达到基本情况。因此,最好最坏情况下的时间复杂度为O(2^n)。这种情况发生在递归树的每一层都会有两个子问题产生,即递归深度为n。

平均情况:由于递归实现的时间复杂度是指数级的,平均情况下的时间复杂度也是O(2^n)。

  1. 迭代:

迭代实现斐波那契数列的算法则只需要计算一次每个数字,时间复杂度相对较低。

迭代实现中,我们使用一个循环来计算斐波那契数列,循环的迭代次数与n值相关。因此,迭代实现的时间复杂度为O(n)。

无论是最好情况还是最坏情况,迭代实现的时间复杂度都是O(n)。

下图是n和2^n复杂度算法效率对比

2^n

n

faster

n=10

1024

10

102.4

n=100

1.20E+30

100

1.20E+28

n=1000

1.07E+301

1000

1.07E+298

n=10000

1.99e3010

10000

1.99e3006

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值