算法复杂度分析
推到大O阶方法:
1.用常数1取代运行时间中的所有加法常数。
2.在修改后的运行次数函数中,只保留最高阶项。
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数。
得到的结果就是大O阶。
常数阶
如果没有循环和递归语句,只是单纯的顺序结构,那么算法复杂度为O(1)。
对于分支分支结构来说,无论真假,执行的次数都是恒定的,不会随n的改变而发生变化,所以单纯的分支结构,其时间复杂度也是O(1)。
线性阶
线性阶的循环结构复杂一些,如:
int sum = 0; //1
for(int i = 1 ; i <= 100 ; i++) //n+1
{
sum+= i; //n
}
printf("%d",sum); //1
该算法共执行了2n+3次,
所以算法复杂度为O(n)
对数阶
int count = 1;
while(count < n)
{
count = count * 2
}
结果为2^x >= n
则x = log2n
所以复杂度为O(logn)
平方阶
int i,j;
for(i = 0 ; i < n ;i++)
{
for(j = 0 ; j < n ;j++)
{
....
}
}
则时间复杂度为O(n^2);
如果内外层的循环次数不一样,那么复杂度就为O(mxn)
常见的时间复杂度
执行次数函数 | 阶 | 非正式术语 |
12 | O(1) | 常数阶 |
2n+3 | O(n) | 线性阶 |
3n^2+2n+1 | O(n^2) | 平方阶 |
5log2n+20 | O(logn) | 对数阶 |
2n+3nlog2n+19 | O(nlogn) | nlogn阶 |
6n^3+2n^2+3n+4 | O(n^3) | 立方阶 |
2^n | O(2^N) | 指数阶 |
常用的时间复杂度所消耗的时间从小到大排序
O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
对于指数级以上的算法基本是无效的不可计算的。
最坏运行时间
最坏运行时间就是该算法在条件下所要运行的最长时间情况,一般说算法复杂度都指的是最坏时间复杂度。
算法控件复杂度
算法的空间复杂度通过计算算法所需要的存储空间实现,算法空间复杂度的计算公式记做:S(n) = O(f(n)),其中,n为问题的规模,f(n)为语句关于n所占存储控件的函数。
指令,常数,变量和输入数据和算法本身没有关系,所以只需要计算算法额外需要的辅助空间就可以。