数据结构与算法(一):复杂度分析

数据结构与算法(一):复杂度分析

最近开始学习王争老师的《数据结构与算法之美》,通过总结再加上自己的思考的形式记录这门课程,文章主要作为学习历程的记录。
广义来说,数据结构是指一组数据的存储结构,算法则是操作数据的一组方法。算法复杂度分为时间复杂度和空间复杂度,在计算算法复杂度时一般用到大O符号。

一、时间复杂度

​ 所有代码执行时间T(n)=O(f(n)),其中f(n)表示每行代码执行的次数总和,O表示T(n)与f(n)表达式成正比,n通常表示数据的规模。

① def cal(n):
②    sum = 0
③    i =1
④    for j in range(n):
⑤        sum += 1
⑥    return sum

以上面的程序为例,②,③都执行了一次,④,⑤都执行了n次,故T(n)=O(2n+2)=O(n)

接下来说一下时间复杂度分析的三种方法:

1.在分析算法和代码时间复杂度时,只需要关注循环执行次数最多的一段代码以上面的程序为例,当 n 很大时,你可以把它想象成 10000、100000,而公式中的低阶,常数和系数都不左右增长趋势,都可以忽略,因此上题的时间复杂度为O(n)。又比如 5 n 4 + 3 n 3 + 2 n 2 + 4 n + 1 5n^4+3n^3+2n^2+4n+1 5n4+3n3+2n2+4n+1的复杂度是O(n^4)

2.加法法则:总复杂度等于量级最大的那段代码的复杂度,如T1(n) = O(f(n)), T2(n)=O(g(n)),则T(n)=T1(n)+T2(n)=max(O(f(n)),O(g(n))) = O(max(f(n),g(n)))

3.乘法法则:嵌套代码的复杂度等于嵌套内外代码的复杂度的乘积。

几种常见的复杂度有(从低阶到高阶)(1),O(logn),O(n),O(nlogn),O( n 2 n^2 n2)

1. O(1)

i,j = 1,2
sum = i+j

2. O(logn)

def fn(n):
    i = 1
    while(i<=n):
        i *= 2

时间复杂度为O( log ⁡ 2 n \log_2n log2n),若是i*=3,则为O( l o g 3 n log_3n log3n)

3. O(n)

def fn(n):
    sum = 0
    for i in range(n):
        sum += 1

4. O(nlogn)

def fn(n):
    sum = 0
    for i in range(n):
        j = 1
        sum += 1
        while(j<=n):
            j *= 2

时间复杂度为O(   n l o g 2 n \ nlog_2n  nlog2n)

5. O( n 2 n^2 n2)

def fn(n):
    sum = 0 
    for i in range(n):
        for j in range(n):
            sum += 1

继续分析时间复杂度,引入了四个概念:最好情况时间复杂度,最坏情况时间复杂度,平均情况时间复杂度,均摊时间复杂度。

def find(array,x):
    a =len(array)
    flag = -1
    for i in range(a):
        if array[i]==x:
            flag = i
            break
    return flag

以上面这个题目为例,最好的情况复杂度是x刚好为数组第一个元素,当寻找到第一个变量时,循环就终止了,则复杂度为O(1),最坏的情况复杂度是x不在数组中,此时复杂度为O(n)。接下来是平均情况复杂度(为了运算简便,我们假设x在数组中和不在数组中的概率各为0.5),则平均计算复杂度为 1 ∗ ( 1 / 2 n ) + 2 ∗ ( 1 / 2 n ) + . . . + n ∗ ( 1 / 2 n ) + n ∗ ( 1 / 2 ) = ( 3 n + 1 ) / 4 1*(1/2n)+2*(1/2n)+...+n*(1/2n)+n*(1/2)=(3n+1)/4 1(1/2n)+2(1/2n)+...+n(1/2n)+n(1/2)=(3n+1)/4

去掉系数和常数,复杂度仍为O(n)

均摊时间复杂度是指在代码执行的所有复杂度情况中绝大部分是低级别的复杂度,个别情况是高级别复杂度且发生时序关系时,可以将个别高级别复杂度均摊到低级别复杂度上。

二、空间复杂度

空间复杂度是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法在计算机存储器上所占用的存储空间,包括存储算法本身所占用的存储空间,算法的输入输出数据所占用的存储空间和算法在运行过程中临时占用的存储空间这三个方面。算法的输入输出数据所占用的存储空间是由要解决的问题决定的,是通过参数表由调用函数传递而来的,它不随本算法的不同而改变。
常见的空间复杂度为O(1),O(n),O( n 2 n^2 n2),且空间复杂度分析比时间复杂度分析要简单很多。

参考资料:王争《数据结构与算法之美》

你可能感兴趣的:(数据结构,复杂度,数据结构与算法)