数据结构与算法(1)--初识和时间复杂度

时间:2020-07-05 13:33:12   收藏:0   阅读:78

算法(1)--时间和空间复杂度

初识

算法定义

算法是独立存在的一种解决问题的方法和思想:

对于算法而言,实现的语言并不重要,重要的是思想

算法特性


复杂度

时间复杂度

定义

? 一般情况下,算法中基本操作重复执行的次数问题规模n的某个函数,用T(n)表示(语句频度),若有某个辅助函数f(n),使得当n趋近于无穷大时T(n)/f(n)极限值不等于零的常数,则称f(n)T(n)同数量级函数。记作T(n)=O(f(n)),称O(f(n))为算法的渐进时间复杂度(O是数量级的符号 ),简称时间复杂度

求解步骤

求解算法时间复杂度的步骤:

  1. 找出算法中的基本语句,计算基本操作执行次数T(n)

    # 基本操作即算法中的每条语句(以;号作为分割),语句的执行次数也叫做语句的频度。在做算法分析时,一般默认为考虑最坏的情况。
    
  2. 计算基本语句的执行次数T(n)数量级

     # 忽略常量、低次幂和最高次幂的系数,令f(n)=T(n)的数量级
    
  3. 用大O来表示时间复杂度

    # 当n趋近于无穷大时,如果lim(T(n)/f(n))的值为不等于0的常数,则称f(n)是T(n)的同数量级函数。记作T(n)=O(f(n)),即为时间复杂度。
    

example_1:

n = 1000  # T(n) = 1
j = 1   # T(n) = 1
num1 = 1   # T(n) = 1
num2 = 2   # T(n) = 1
for i in range(0, n):   # T(n) = n
    num1 += 1   # T(n) = n
    while j < n:  # T(n) = n*log(n), 以2为底
        j *= 2  # T(n) = n*log(n), 以2为底
        num2 += 1  # T(n) = n*log(n), 以2为底
print(num1, num2)  # T(n) = 1
  1. 总的T(n):

    \[T(n) = 5 + 2n + 3nlog_2n \]

  2. 忽略掉T(n)中的常量、低次幂和最高次幂的系数,数量级

    \[f(n) = nlog_2n \]

  3. 求极限

    \[lim(T(n)/f(n)) = lim((3nlog_2n + 2n + 4)/(nlog_2n) = 3 \]

    所以时间复杂度可以用大O表示,为

    \[O(f(n)) = O(nlog_2n) \]

简化的计算步骤:

可以看出,决定算法复杂度的是执行次数最多的语句,这里是num2 += 1j *= 2一般也是最内循环的语句。并且,通常将求解极限是否为常量也省略掉?

  1. 找到执行次数最多的语句
  2. 计算语句执行次数的数量级
  3. 大O来表示时间复杂度

example_1

# 1.执行次数最多的语句为
while  j < n:
    j *= 2
    num2 += 1
T(n) = 3n*log(n) 

# 2.数量级
f(n) = n*log(n)

# 3.求极限及大O表示
T(n) = O(nlog(n))

几种可能

分析算法,存在的几种可能:

一些规则

常见的时间复杂度算法:

执行次函数举例--总的T(n) 时间复杂度 非正式术语
12 O(1) 常数阶
2n + 3 O(n) 线性阶
3n^2 + 2n + 1 O(n^2) 平方阶
5log(n) + 20 O(log(n)) 对数阶
2n + 3nlog(n) + 19 O(nlog(n)) nlog(n)阶
6n^3 + 2n^2 + 3n + 4 O(n^3) 立方阶
2^n O(2^n) 指数阶
n! + nlog(n) + 15 O(n!) 阶乘

所消耗的时间从小到大:

\[O(1) < O(log(n)) < O(n) < O(nlog_2(n)) < O(n^2) < O(n^3) < O(2^n) < O(n!) < O(n^n) \]

技术图片

示例演练

example_2

n = 1000
x = 1

for i in range(0, n):
    x += 1  # T(n) = n

for i in range(0, n):
    for j in range(0, n):
        x += 1  # T(n) = n*n
print(x)

分析:注意:T(n)为执行次数最多语句的频度


example_3

def func(n):
    for i in range(n):
        for j in range(i, n):
            print("Hello World j = %s" % j)  # T(n) = (n^2)/2 + n/2

分析:注意:==T(n)为执行次数最多语句的频度


example_4

def func(n):
    if n <= 1:
        return 1
    else:
        return func(n - 1) + func(n - 2)

分析:

显然运行次数,T(0) = T(1) = 1,同时 T(n) = T(n - 1) + T(n - 2) + 1,这里的 1 是其中的加法算一次执行。
显然 T(n) = T(n - 1) + T(n - 2) 是一个斐波那契数列,通过归纳证明法可以证明,当 n >= 1 时 T(n) < (5/3)^n,同时当 n > 4 时 T(n) >= (3/2)^n。
所以该方法的时间复杂度可以表示为 O((5/3)^n),简化后为 O(2^n)。

空间复杂度

类似于时间复杂度的讨论,一个算法的空间复杂度(Space Complexity)S(n)定义为该算法所耗费的存储空间它也是问题规模n的函数。渐近空间复杂度也常常简称为空间复杂度。
空间复杂度(Space Complexity)是对一个算法在运行过程中临时占用存储空间大小的量度。一个算法在计算机存储器上所占用的存储空间,包括:


常见算法空间复杂度:


评论(0
© 2014 mamicode.com 版权所有 京ICP备13008772号-2  联系我们:gaon5@hotmail.com
迷上了代码!