前言
复杂度是数据结构基础第一个要学习的重要知识,在面试或者笔试中也经常考到。
一、 复杂度是什么?
复杂分为两种
1.时间复杂度 2.空间复杂度
在刚开始了解复杂度的时候,会把时间复杂度误认为算法运行时间,空间复杂度误认为代码所占空间,其实不然。
二、时间复杂度
1.概念
时间复杂度并不是我们习惯性的认为代码运行时间,而是算法中基本操作的次数。在计算及科学中算法的时间复杂度是一个函数,它定量的描述了该算法的运行时间。
2.大O渐进表示法
void fun1(int n)
{
int count=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
count++;
}
}
for(i=0;i<2*n;i++)
{
count++;
}
for(i=0;i<10;i++)
{
count++;
}
}
上面的代码运行了多少次?
我们可以很轻易的算出来Fun1的基本操作次数
F(N)=N^2+2*N+10
时间复杂度为O(N^2)
到这里肯定会有疑问为什么是N^2,不是N^2+2*N+10吗?
接下来介绍一下怎么推导出大O阶
3.推导大O阶方法
3.1推导
a.用常数1来取代运行时间中的加法常数。
b.在修改后的运行次数函数中,只保留最高阶项
c.如果最高阶项存在且不是1,则去除与这个项目相乘的常数。得到的结果就是大O阶
3.2情况
最坏情况:任意输入规模的最大运行次数(上界)
平均情况:任意输入规模的期望运行次数
最好情况:任意输入规模的最小运行次数(下届)
例如:在一个1~n的数组中寻找有个数x
最坏情况:N次找到
平均情况:N/2次找到
最好情况:1次找到
在实际中一般关注的是算法的最坏情况,所以上面例子时间复杂度为O(N)。
三、空间复杂度
1.概念
空间复杂度是对一个算法在运行过程中临时占用储存空间大小的量度。空间复杂度不是程序占用了多少个字节的空间,而是计算程序变量的个数。与时间复杂度相似也使用大O渐进表示法。
2.例子
void Bubble(int* a,int n)
{
assert(a);
for(size_t end=n;end>0;end--)
{
int exchange=0;
for(size_t i=0;i<end;i++)
{
if(a[i-1]>a[i])
{
Swap(&a[i-1],&a[i]);
exchange=1;
}
}
if(exchange==0)
{
break;
}
}
}
上面代码的空间复杂度为O(1)
肯定会有很多人疑问为什么
此代码变量有
end、i、exchange;
因为i每次在栈区上创建然后就被销毁所以只占一个空间
所以变量为常数个根据大O渐进表示法规则所以为O(1)
总结
到这里相信大家对时间复杂度和空间复杂度就有了一定的认识,但这里只是讲解了一下概念和几种简单的计算情况,还有许多复杂的情况得靠大家自己去了解和领悟。