对一个算法而言,评估一个算法的优劣除了能否正确的完成制定任务外就要看一个算法的空间复杂度和时间复杂度,一般情况下,我们认为的是看最坏情况下的空间复杂度和最差时间复杂度。需要注意的是,空间复杂度和时间复杂度往往不可得兼,解决同一个任务一个时间复杂度低的算法往往会空间复杂度较高,牺牲空间来换取时间,随着计算机的发展,一般情况下认为时间复杂度低的算法更优秀。
1.时间复杂度
时间复杂度常用大O符号表示,取有关输入的数的最高项如下
int n;
scanf("%d",&num);
int num = 0;
for(;num<n;num++)
printf("%d",num);
printf函数运行次数与n有关则其时间复杂度为O(n).
要注意的是时间复杂度只与输入的值的最高项有关系,如下为二分搜索的代码
i=0;
while(i<n){i++};//这条语句执行了N次
i=0;
j=0;
while(i<n)
{ while(j<n)
{
j++;//这条语句执行了n^2次
}i++;j=0;
}
其代码运行为n+n^2,但是复杂度为O(n^2).
一个代码如果没有输入项其运行代码条数固定,则无论多长都是O(1).
利用递归写法的斐波那契数列
int Fib(int N)
{
if (N < 3) //当N<3时,斐波那契数为1
return 1;
return Fib(N - 1) + Fib(N - 2);//函数递归
}
int main()
{
int n = 0;
scanf("%d",&n);
printf("%d",Fib(n));
return 0;
}
算法可表示为
当输入为5的时候,可以看出深度为5,其中运算9次及2^3+1次运算,算法复杂度为O(2^n);
常见的时间复杂度顺序为
O(1)<O(log2n)<O(n)<O(nlog2n)<O(n2)<O(n3)<…<O(2n)<O(n!)
2.空间复杂度
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度,记做S(n)=O(f(n))。比如直接插入排序的空间复杂度是O(n^2),空间复杂度是O(1) 。而一般的递归算法就要有O(n)的空间复杂度了,因为每次递归都要存储返回信息。一个算法的优劣主要从算法的执行时间和所需要占用的存储空间两个方面。