复杂度和空间复杂度百科

通过字面意思可以知道

  • 时间复杂度:就是说执行算法需要消耗的时间长短,越快越好。
  • 空间复杂度:就是说执行当前算法需要消耗的存储空间大小,也是越少越好

表示方法
我们一般用“大O符号表示法”来表示时间复杂度:T(n) = O(f(n))
n是影响复杂度变化的因子,f(n)是复杂度具体的算法。

时间和空间复杂度意义

评价一个算法的效率主要是看它的时间复杂度和空间复杂度情况。

可能有的开发者接触时间复杂度和空间复杂度的优化不太多(尤其是客户端),但在服务端的应用是比较广泛的。在巨大并发量的情况下,小部分时间复杂度或空间复杂度上的优化都能带来巨大的性能提升,是非常有必要了解的。

时间复杂度

常见的时间复杂度量级如下:

  • 常数阶O(1)
  • 线性阶O(n)
  • 对数阶O(logN)
  • 线性对数阶O(nlogN)
  • 平方阶O(n²)
  • 立方阶O(n³)
  • K次方阶O(n^k)
  • 指数阶(2^n)

1. 常数阶O(1)

int a = 1;
int b = 2;
int c = 3;

大O符号表示法并不是用于来真实代表算法的执行时间的,它是用来表示代码执行时间的增长变化趋势的。
如上代码即使成千上万,其算法并未边长,其时间复杂度仍为O(1)。

  1. 线性阶O(n)
for(i = 1; i <= n; i++) {// 执行n次
   j = i;// 执行n次
}

n为几,则for内部代码块就需要运行多少次,所以它的时间复杂度其实是O(n)。

3. 对数阶O(logN)

int i = 1;
while(i < n) {
    i = i * 2;
}

可以看到每次循环的时候 i 都会乘2,那么总共循环的次数就是log2n,因此这个代码的时间复杂度为O(log2n)。
这里的底数对于研究程序运行效率不重要,写代码时要考虑的是数据规模n对程序运行效率的影响,常数部分则忽略,所以成了O(logn)

同样的,如果不同时间复杂度的倍数关系为常数,那也可以近似认为两者为同一量级的时间复杂度。

4. 线性对数阶O(nlogN)

for(m = 1; m < n; m++) {
    i = 1;
    while(i < n) {
        i = i * 2;
    }
}

线性对数阶O(nlogN) 其实非常容易理解,将时间复杂度为O(logn)的代码循环N遍的话,那么它的时间复杂度就是 n * O(logN),也就是了O(nlogN)。

5. 平方阶O(n²)

for(x = 1; i <= n; x++){//执行你次
   for(i = 1; i <= n; i++) {//执行 N*n次
       j = i;  //执行 N*n次
    }
}

把 O(n) 的代码再嵌套循环一遍,它的时间复杂度就是 O(n²) 了。

6.立方阶O(n³)、K次方阶O(n^k)
参考上面的O(n²) 去理解就好了,O(n³)相当于三层n循环,其它的类似。

时间复杂度分析
通常用T(n)表示代码执行时间,n表示数据规模大小,f(n)表示代码执行综合次数。

在O(n)例子中执行次数为2n,如果没行执行时间t,则执行时间2nt,可以表示f(n)=2nt,
在O(n²)例子中执行次数为2n,如果没行执行时间t,则执行时间2nt,可以表示f(n)=(2n²+n)t。

代码的执行时间 T(n)与每行代码的执行次数 n 成正比,人们把这个规律总结成这么一个公式:T(n) = O(f(n))。大O时间复杂度并不具体表示代码真正的执行时间,而是表示代码执行时间随数据规模增长的变化趋势。所以,也叫作渐进时间复杂度,简称时间复杂度。

当n变得越来越大时,公式中的低阶,常量,系数三部分影响不了其增长趋势,所以可以直接忽略他们,只记录一个最大的量级就可以了,所以两个例子实际他们的时间复杂度应该记为:T(n)=O(n) ,T(n)=O(n*n)

空间复杂度

1. 空间 O(1)
如果算法执行所需要的临时空间不随着某个变量n的大小而变化,即此算法空间复杂度为一个常量,可表示为 O(1)。

int i = 1;
int j = 2;
++i;
j++;
int m = i + j;

2. 空间 O(n)

int[] arr = new int[n]

分配空间只和n有关

稳定性

假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。

需要注意的是,排序算法是否为稳定的是由具体算法决定的,不稳定的算法在某种条件下可以变为稳定的算法,而稳定的算法在某种条件下也可以变为不稳定的算法。

如下冒泡排序中将条件修改为if (arr[j] >= arr[j + 1]),则稳定性将从稳定变为不稳定。

          if (arr[j] > arr[j + 1]) {
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章