算法复杂度(大O法) 数据结构与算法 第二讲_算法分析

1. 算法分析角度:

可从算法占用的空间和时间两个方面对算法的优劣进行评价比较

从时间方面:
大O法:

只考虑算法中起着较大影响的部分。如:5n2+27n+1005,则为O(n2).

例1:
a = 3
b = 4
c = 5
for i in range(n):
    for j in range(n):
        x = i * i
        y = j * j
        z = i * j
for k in range(n):
    w = a * k + 45
    v = b * b
d = 33

上面这个程序的T(n)=3+3n2+2n+1, 数量级为O(n2)

例二:

创建一个从0到999的列表,方法有很多种,不同方法的算法复杂度不一样。

在此我们讨论用列表解析式、for循环和直接用range的复杂度。

为此,我们需借助timeit模块对三种函数计时,每种方法均运行1000次。

from timeit import Timer
def test1():
    l = [i for i in range(1000)]
    
def test2():
    l = []
    for i in range(1000):
        l.append(i)
    
def test3():
    l = list(range(1000))
    
t1 = Timer('test1()','from __main__ import test1')
print('test1: %f second'% t1.timeit(number=1000))

t2 = Timer('test2()','from __main__ import test2')
print('test2: %f second'% t2.timeit(number=1000))

t3 = Timer('test3()','from __main__ import test3')
print('test3: %f second'% t3.timeit(number=1000))

得出结果:

test1: 0.043906 second
test2: 0.074032 second
test3: 0.016611 second

2. Python中列表List基本操作的大O数量级:

index()取值和赋值,append(),pop()都是O(1)。
sort()为O(nlogn),其他包括pop(i)大多数为O(n)。
接下来验证一下pop()和pop(i)的区别。

import timeit

x = list(range(100000))
popzero = timeit.Timer('x.pop(0)','from __main__ import x')
popnormal = timeit.Timer('x.pop()','from __main__ import x')

print('popzero: ',popzero.timeit(number=10000))
print('popnormal: ',popnormal.timeit(number=10000))

得到结果:

popzero:  0.2733208999998169
popnormal:  0.000696299997798632

可以看出差别是非常大的。因为Python为了保持数据想的有序性,在用pop删去元素时,会讲该元素后面的值一一向前复制,因此增大了复杂度。

3. 字典dict()基本操作的大O数量级:

get item, set item, del item, contains(in)为O(1)。
copy和iteration(迭代)为O(n)。

list和dict in操作(判断元素是否存在) 运行时间对比:
import timeit,random
print('n   list   dict')
for i in range(10000,100001,10000):   
    t_in = timeit.Timer('random.randrange(%d) in x'%i,
                     'from __main__ import random,x')
    
    x = list(range(i))
    list_time = t_in.timeit(number=1000)
    
    x = dict().fromkeys(range(i),None)
    dict_time = t_in.timeit(number=1000)
    
    print('%d  %.3f  %.3f'%(i,list_time,dict_time))

得到结果:

n   list   dict
10000  0.068  0.001
20000  0.121  0.001
30000  0.185  0.001
40000  0.243  0.001
50000  0.302  0.001
60000  0.361  0.001
70000  0.412  0.001
80000  0.484  0.001
90000  0.582  0.001
100000  0.630  0.001

可以看出随着数据项增多,列表在判断元素是否存在(in函数)的算法复杂度是呈线性增加的,而字典则是不变的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值