数据结构C语言 《一》斐波那契数 时间,空间复杂度详述
Posted 程序猿是小贺
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构C语言 《一》斐波那契数 时间,空间复杂度详述相关的知识,希望对你有一定的参考价值。
斐波那契数 时间,空间复杂度
大O的渐进表示法
推导大O阶方法:
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
注意:有些算法的时间复杂度存在最好、平均和最坏情况:
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
例如:在一个长度为N数组中搜索一个数据x
最好情况:1次找到
最坏情况:N次找到
平均情况:N/2次找到
在实际中一般情况关注的是算法的最坏运行情况,所以数组中搜索数据时间复杂度为O(N)
时间复杂度
时间复杂度的概念
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法的时间复杂度。
递归算法的时间复杂度:递归的总次数*每次递归的数量。
斐波那契数列,又称黄金分割数列,指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……
递归求斐波那契数时间复杂度为O(2^N)
时间复杂度分析:
求解F(n),必须先计算F(n-1)和F(n-2),计算F(n-1)和F(n-2),又必须先计算F(n-3)和F(n-4)…以此类推,直至必须先计算F(1)和F(0),然后逆推得到F(n-1)和F(n-2)的结果,从而得到F(n)要计算很多重复的值,在时间上造成了很大的浪费,算法的时间复杂度随着N的增大呈现指数增长,时间的复杂度为O(2^n),即2的n次方
long long Fib(size_t N)
return N < 2 ? N : Fib(N - 1) + Fib(N - 2);
这种方法看似代码简单,实际操作起来非常繁琐,有兴趣的朋友可是试试给个100运行一下,不过可能得等上几个小时才会出结果哦
递归求斐波那契数时间复杂度为O(N)
尾递归法
如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。当递归调用是整个函数体中最后执行的语句且它的返回值不属于表达式的一部分时,这个递归调用就是尾递归。
long long Fib(long long first, long long second, long long n)
if (n < 3)
return 1;
if (3 == n)
return first + second;
return Fib(second, first + second, n - 1);
用循环方法来实现时间复杂度为O(N)的斐波那契数
long long Fib(int n)
long long ret = 0;
long long first = 1, second = 1;
for (int i = 3; i <= n; i++)
ret = first + second;
first = second;
second = ret;
return ret;
空间复杂度
空间复杂度的概念
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。=空间复杂度算的是变量的个数。空间复杂度计算规则基本跟时间复杂度类似,也使用大O渐进表示法。
递归算法的空间复杂度:递归的深度*每次递归创建变量的个数。
空间复杂度为O(N)的斐波那契数
long long Fib(int n)
long long*p = (long long*)malloc(sizeof(long long)*n);
assert(p != NULL);
p[0] = 1, p[1] = 1;
for (int i = 2; i < n; i++)
p[i] = p[i - 1] + p[i - 2];
long long ret = p[n - 1]; //定义一个临时变量去接收p[n-1],以便于最后释放这个内存空间
free(p);
return ret;
以上是关于数据结构C语言 《一》斐波那契数 时间,空间复杂度详述的主要内容,如果未能解决你的问题,请参考以下文章