目录:1.算法效率 2.时间复杂度 3.空间复杂度
1.算法效率
分为两种:时间效率和空间效率。时间效率被称为时间复杂度,时间复杂度主要衡量算法的运行速度,而空间复杂度主要衡量算法所需的额外空间。
2.时间复杂度:
(1)时间复杂度定义:算法的时间复杂度为一个函数,定量描述该算法的运行时间。
算法中的基本操作的执行次数,为算法的时间复杂度。
(2)大O的渐进表示法
//请计算一个Func1基本操作执行了多少次?
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);
}
Func1执行的基本操作次数:
F(N)=N^2+2*N+10;
实际中,计算时间复杂度时,并不一定要计算精确的执行次数,只需大概执行次数,此时使用大O的渐进表示法。
大O符号:用于描述函数渐进行为的数学符号。
【1.用常数1取代运行时间中的所有加法常数
2.在修改后的运行次数函数中,只保留最高阶项。
3.如果最高阶项存在且不为1,则去除与这个项目相乘的常数,得到的结果即为大O阶。】
使用此方法,可以去除那些对结果影响不大的项。
因此,使用大O的渐进表示法后,Func1的时间复杂度为O(N^2)
此外,有些算法的时间复杂度存在最好、平均和最坏情况:
最好情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下界)
【在实际中一般情况关注算法的最坏运行结构】
例子:在一个长度为N的数组中搜索一个数据x
最好情况:1次找到
平均情况:N/2次
最坏情况:N次
实例:计算二分查找的时间复杂度
int BinarySearch(int* a,int n,int x)
{
assert(a);
int begin=0;
int end=n;
while(begin<end)
{
int mid=begin+((end-begin)>>1);
if(a[mid]<x)
begin=mid+1;
else if(a[mid]>x)
end=mid;
else
return mid;
}
return -1;
}
答案:N=2^x (x为查找次数)
实例:计算阶乘递归Factorial的时间复杂度
long long Factorial(size_t N)
{
return N<2?N:Factorial(N-1)*N;
}
答案:0(N)
递归算法如何计算:递归次数*每次递归函数的次数
3.空间复杂度
空间复杂度是一个算法在运行过程中临时存储空间大小的量度。空间复杂度算的是变量的个数。也用大O渐进表示法。
递归算法的空间复杂度:递归的栈帧深度,因为递归函数要建立栈帧,递归要消耗空间
总结:
时间复杂度计算大概的运行次数
空间的复杂度计算大概定义的变量个数