时间复杂度和空间复杂度
时间复杂度和空间复杂度定义
首先要理解的就是在我们生活中基本上所有的东西都可以用时间或者空间来表示。编程也是一样如何去评判程序的好坏和效率的高低呢?当我们不能保证设备一样的情况下也就是建立在公平之上判断时,我们就引入了时间复杂度和空间复杂度这两个评判标准。
时间复杂度定义:
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间。一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道。但是我们需要每个算法都上机测试吗?是可以都上机测试,但是这很麻烦,所以才有了时间复杂度这个分析方式。一个算法所花费的时间与其中语句的执行次数成正比例,算法中的基本操作的执行次数,为算法 的时间复杂度。
其实白话的来说就是函数在操作中执行的次数。
空间复杂度定义:
空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度 。空间复杂度不是程序占用了多少 bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践 复杂度类似。
简单来说就是占用存储空间的大小。
大O的渐进表示法
定义:
算法的时间复杂度通常用大O符号表述,定义为T[n] = O(f(n))。称函数T(n)以f(n)为界或者称T(n)受限于f(n)。 如果一个问题的规模是n,解这一问题的某一算法所需要的时间为T(n)。T(n)称为这一算法的“时间复杂度”。当输入量n逐渐加大时,时间复杂度的极限情形称为算法的“渐近时间复杂度”。
例如:
void Func1(int N)
{
int count = 0;
for (int i = 0; i < N ; ++ i)
{
for (int j = 0; j < N ; ++ j)
{
++count;
}
}
for (int k = 0; k < 2 * N ; ++ k)
{
++count;
}
int M = 10;
while (M--)
{
++count;
}
printf("%d\n", count);
}
这个代码的空间复杂度是N^2+2*N+M(10)。
实际中我们计算时间复杂度时,我们其实并不一定要计算精确的执行次数,而只需要大概执行次数。
简单来说就是按N次方来算。
1、用常数1取代运行时间中的所有加法常数。
2、在修改后的运行次数函数中,只保留最高阶项。
3、如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶。
这样判断上述的复杂度就是0(N^2).
当然后空间复杂度也是如此。
举例详解斐波那契数列( Fibonacci
)
阶乘:
long long Fibonacci(size_t N)
{
return N < 2 ? N : Fibonacci(N-1)*N;
}
当N为5时,Fib(4)*5
Fib(3)*4
Fib(2)*3
Fib(1)*2
按这个顺序乘下来调用了N-1次所以为O(n)
递归:
long long Fibonacci(size_t N)
{
return N < 2 ? N : Fibonacci(N-1)+Fibonacci(N-2);
}
当N为5时,Fib(4)+Fib(3)
Fib(3)+Fib(2) Fib(2)+Fib(1)
… … … … … … … … … … … … … …
这样依次循环第一行就是2^1
第二行就是2^2
依次下来是2^N-1
按这个顺序调用下来就是为O(2^N).
利用大O渐进表示法。