数据结构0310
2018-03-14 09:30 SummerVan 阅读(179) 评论(0) 收藏 举报算法时间复杂度
定义:在分析算法时,语句的总执行次数t(n)是关于问题规模n的函数,从而分析T(n)随n的变化情况并确定t(n)的数量寄
算法的时间复杂度记做t(n)=O(fn)(ps:f(n)是问题规模n的某个函数),这个表示随着n的增大,算法执行时间的增长
率和f(n)的增长率相同,称作算法的渐进时间复杂度,简称为时间复杂度 这种记法叫大O记法 一般情况下随着n的增大t(n)
增长最慢的算法为最优算法
推导大O阶:
1.用常数1取代运行时间中所有的加法常数
2.在修改后的运行次数函数中,只保留最高阶项
3.如果最高阶项存在且不是1,则去除与这个项相乘的常数
得到的就是大O阶
(1)常数阶
let sum = 0; n = 100; //执行一次
sum= (n+1)*n/2; //执行一次
return sum //执行一次算法运行次数函数是f(n) = 3 按照推论方法时间复杂度为O(1);
假设sum = (n+1)*n/2有十句 时间复杂度还是为O(1) 因为无论n为多少 执行的次数都是恒定的 不管这个f(n)常数是多少 都记做O(1)
对于分支结构来说 无论是真还是假 执行的次数都是恒定的 所以不包含在循环结构里的单纯的分支结构时间复杂度也是O(1)
(2)线性阶
分析算法的复杂度,关键是分析循环结构的运行情况
例:最典型的for循环结构 大O阶为 O(n);
(3)对数阶
let num = 1;
while (num < n)
{
num = num * 2;
}
由于每次num乘以2之后 就离n越小 也就是有多少个2相乘后大于n就会退出循环 2的x次方 = n ; x = log2n 所以为O(logn)
(4)平方阶
例:循环嵌套 里面的大O阶为O(n)外面为O(m) 所以总的来说大O阶为O(m*n)
所以循环的时间复杂度等于循环体的复杂度乘以该循环体运行的次数
例:for(var i = 0; i < n; ++i)
{
for (var j = i; j < n;++j)//j=i不是j=0
{
//时间复杂度为O(1)的程序步骤
}
}
当i = 0时 内循环执行n次 当i = 1 是执行n-1次当i = n -1时执行1次 所以总执行次数
n+(n -1)+(n-2)+·······+1 = n(n+1)/2 = n^2/2 + n/2 用上面推导大O阶方法可推断出这段代码时间复杂度为O(n^2)
对方法调用的复杂度分析
如果函数方法执行语句是O(1)则总的时间复杂度为O(n) 若函数方法执行O(n)则总时间复杂度为O(n^2) 以此类推
常见的时间复杂度O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
最好情况O(1)和最坏情况O(n^n) 通常除非特别指定一般提到的运行时间都为最坏时间
算法空间复杂度计算方式:S(n) = O(f(n)),n为问题规模 f(n)为语句关于n所占存储空间的函数
浙公网安备 33010602011771号