一、算法的五大特性
- 输入: 算法具有0个或多个输入
- 输出: 算法至少有1个或多个输出
- 有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
- 确定性:算法中的每一步都有确定的含义,不会出现二义性
- 可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
二、时间复杂度与“大O记法”
- 我们假定计算机执行算法每一个基本操作的时间是固定的一个时间单位,那么有多少个基本操作就代表会花费多少时间单位。算然对于不同的机器环境而言,确切的单位时间是不同的,但是对于算法进行多少个基本操作(即花费多少时间单位)在规模数量级上却是相同的,由此可以忽略机器环境的影响而客观的反应算法的时间效率。
- 对于算法的时间效率,我们可以用“大O记法”来表示。
- “大O记法”:对于单调的整数函数f,如果存在一个整数函数g和实常数c>0,使得对于充分大的n总有f(n)<=c*g(n),就说函数g是f的一个渐近函数(忽略常数),记为f(n)=O(g(n))。也就是说,在趋向无穷的极限意义下,函数f的增长速度受到函数g的约束,亦即函数f与函数g的特征相似。
- 时间复杂度:假设存在函数g,使得算法A处理规模为n的问题示例所用时间为T(n)=O(g(n)),则称O(g(n))为算法A的渐近时间复杂度,简称时间复杂度,记为T(n)
三、最坏时间复杂度
- 分析算法时,存在几种可能的考虑:
算法完成工作最少需要多少基本操作,即最优时间复杂度
算法完成工作最多需要多少基本操作,即最坏时间复杂度
算法完成工作平均需要多少基本操作,即平均时间复杂度
四、时间复杂度的几条基本计算规则
- 基本操作,即只有常数项,认为其时间复杂度为O(1)
- 顺序结构,时间复杂度按加法进行计算
- 循环结构,时间复杂度按乘法进行计算
- 分支结构,时间复杂度取最大值
- 判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
- 在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度。
五、常见时间复杂度大小排序
- O(1) < O(logn) < O(n) < O(nlogn) < O(n2) < O(n3) < O(2n) < O(n!) < O(nn)
六、Python内置类型性能分析
1. timeit模块
- timeit模块可以用来测试一小段Python代码的执行速度。
- class timeit.Timer(stmt=‘pass’, setup=‘pass’, timer=)
Timer是测量小段代码执行速度的类。
stmt参数是要测试的代码语句(statment);
setup参数是运行代码时需要的设置;
timer参数是一个定时器函数,与平台有关。 - timeit.Timer.timeit(number=1000000)
Timer类中测试语句执行速度的对象方法。number参数是测试代码时的测试次数,默认为1000000次。方法返回执行代码的平均耗时,一个float类型的秒数。
2. list测试操作
from timeit import Timer
def t1():
li=[]
for i in range(10000):
li.append(i)
def t2():
li=[]
for i in range(10000):
li =li + [i]
def t21():
li=[]
for i in range(10000):
li +=[i]
def t3():
li=[i for i in range(10000)]
def t4():
li=list(range(10000))
def t5():
li=[]
for i in range(10000):
li.extend([i])
timer1=Timer('t1()','from __main__ import t1')
print('append:',timer1.timeit(1000))
timer2=Timer('t2()','from __main__ import t2')
print('+:',timer2.timeit(1000))
timer21=Timer('t21()','from __main__ import t21')
print('+=:',timer21.timeit(1000))
timer3=Timer('t3()','from __main__ import t3')
print('for i in range(10000):',timer3.timeit(1000))
timer4=Timer('t4()','from __main__ import t4')
print('list(range(10000)):',timer4.timeit(1000))
timer5=Timer('t5()','from __main__ import t5')
print('extend:',timer5.timeit(1000))
print("****************************************************")
def t6():
li=[]
for i in range(10000):
li.append(i)
def t7():
li=[]
for i in range(10000):
li.insert(0,i)
timer6=Timer('t6()','from __main__ import t6')
print('append:',timer6.timeit(1000))
timer7=Timer('t7()','from __main__ import t7')
print('insert:',timer7.timeit(1000))
运行结果:
append: 0.7073922
+: 172.9795022
+=: 0.7968132999999966
for i in range(10000): 0.3180134000000123
list(range(10000)): 0.11936589999999114
extend: 1.0216904000000113
****************************************************
append: 0.6718296000000237
insert: 36.8306365
3. list内置操作的时间复杂度
4. dict内置操作的时间复杂度