递归,迭代和矩阵法求斐波那契数列

1.内容:

用递归,迭代和矩阵法求斐波那契数列,并对比运行时间。

2.代码:

#include<stdio.h>

#include<time.h>//clock函数头文件

unsigne dlong long a[100000000];//用于存迭代法的斐波那契数列

double diedai(int n)//迭代法求斐文那契数列 (从第一个数开始求,直到求出要的数为止)

{

    int i;

    a[1]=0;//第一个数

    a[2]=1;//第二个数

    clock_t beg,end;//起始时间和结束时间

    double time;

    beg=clock();//迭代法起始时间

    for(i=3;i<=n;i++)//循环从第三个数开始,直到求出第n个斐波那契数

    {

        a[i]=a[i-1]+a[i-2];//根据前两个数求出第i个(后一个)斐波那契数

    }

    printf("迭代法计算第%d个数是%lld\n",n,a[n]);

    end=clock();//迭代法结束时间

    time=(double)(end- beg)/CLOCKS_PER_SEC;//迭代法运行时间

    return time;

}

unsigned long long digui(int n)//递归算法计算

{

   

    if(n==1)//当n==1时结束递归或求第一个数

    {

        return 0;

    }

    else if(n==2)//当n==2时结束递归或求第一个数

    {

       return 1;

    }

    else

    {

        return digui(n-1)+digui(n-2);//调用本身函数计算前两个数并相加,直到符合结束递归条件为止

    }

}

double juzhen(int n)

{

    unsigned long long a[2][2],b[2][2],c[2][2];//a数组用于存起始矩阵,b数组刚开始用于存起始矩阵,后存储待求矩阵的前一个矩阵,c数组用于求待求矩阵

    a[1][1]=b[1][1]=1;//将a,b付初始矩阵

    a[1][2]=b[1][2]=1;

    a[2][1]=b[2][1]=1;

    a[2][2]=b[2][2]=0;

    int i,j,k,p,q;

    clock_t beg,end;

    double time;

    beg=clock();//矩阵法起始时间

    if(n==1)

    {

        printf("第一个数为%lld\n",a[2][2]);//求第一个数时

    }

    else

    {

        for(k=n;k>1;k--)//k循环循环一次b矩阵都乘一个原始矩阵得到c矩阵

        {

            for(i=1;i<=2;i++)//i循环循环一次计算矩阵的一行

            {

                for(j=1;j<=2;j++)//j循环循环一次计算矩阵的一个数   

                {

                    if(j==1)//j为1和j为2时求c矩阵的公式不同,因此分情况求c

                    {

                        c[i][j]=b[i][j]*a[1][1]+b[i][j+1]*a[2][1];

                    }

                    else if(j==2)

                    {

                        c[i][j]=b[i][j-1]*a[1][2]+b[i][j]*a[2][2];

                    }

                }

            }

            for(p=1;p<=2;p++)//将c矩阵赋值给b矩阵,便于用b矩阵乘初始矩阵求下一个斐波那契数

            {

                for(q=1;q<=2;q++)

                {

                    b[p][q]=c[p][q];

                }

            }

        }

        printf("第%d个数是%lld\n",n,c[2][2]);//c数组即为初始矩阵的n次幂,其中c[2][2]便存着第n个斐波那契数

    }

    end=clock();//结束时间

    time=(double)(end- beg)/CLOCKS_PER_SEC;//运行时间

    return time;

}

intmain()

{

    int n;

    printf("请输入n:");

    scanf("%d",&n);

    printf("迭代法运行时间%f s\n",diedai(n));

    clock_t beg,end;//起始时间和结束时间

    double time;//递归运行时间

    unsigned long long num;//存储返回的菲文那契数

    beg=clock();

    num=digui(n);//存储返回的菲文那契数

    end=clock();

    printf("递归法计算第%d个数是%lld\n",n,num);

    time=(double)(end- beg)/CLOCKS_PER_SEC;//递归运行时间

    printf("递归法运行时间%f s\n",time);

    printf("矩阵法运行时间为%fs",juzhen(n));

    return 0;

}



3.结论:

1.理论结果:在理论上递归排序运行时间最长,因为递归本质上是栈,每次计算没有记录前面两个数的值,导致有大量的重复计算,会导致内存溢出,其次是矩阵法,迭代法运行时间最快。

2.实际结果:在实际上递归排序运行时间最长,其次是矩阵法,迭代法运行时间太快无法比较。


猜你喜欢

转载自blog.csdn.net/yang03_26/article/details/80773863
今日推荐