以一道数学题,引入数据结构与算法,比较运算效率,看懂时间复杂度
import time
start_time = time.time()
# for a in range(1001):
# for b in range(1001):
# for c in range(1001):
# if 1000 == a + b + c and a**2 + b**2 == c**2:
# print("a, b, c: %d, %d, %d" % (a, b, c))
# 280.911694
# 1000 * 1000 * 1000 * 10 = 10 * 1000^3 = T
# T(n) = 10 * n^3 = O(n^3)
for a in range(1001): # 2000
for b in range(1001):
c = 1000 - a -b # 3
if a**2 + b**2 == c**2: # 5
print("a, b, c: %d, %d, %d" % (a, b, c)) # 2
# 1000 * 1000 * (3+5+2) = 10 * 1000^2 = T
# 时间复杂度 T(n) = 10 * n^2 O(n^2)
# 基本运算总数 * 基本运算的单位时间
# cost: 1.838194
end_time = time.time()
cost = end_time - start_time
print("cost: %f" % cost)
# li = [1,3,2,7,3,2,4,6] -> [1, 2, 3, 3, 4,5 6]
# T(n)
# [1,2,3,4,5,6,7]
总的时间=基本运算总数*基本运算的单位时间
我理解的时间复杂度:算法完成所需要的时间效率
我理解的空间复杂度:算法完成所需要消耗的存储空间
我理解的算法复杂度: 时间+空间
时间复杂度的演变:
基本运算总数--->问题规模N--->函数T(n)--->初始时间复杂度--->大"O"表示法:T(n)=O(n/1/k)
时间复杂度的分类:
1.最坏时间复杂度 2.最优时间复杂度 3.平均时间复杂度
时间复杂度的计算规则:
1.常数项---->时间复杂度O(1)
2.顺序结构---->加法计算
3.循环结构(倍数关系)---->乘法计算
4.分支结构:计算( f / else )最大执行次数的时间复杂度
5.判断算法效率:取最高次项,(次要项和常数项忽略)
常见的时间复杂度之间的关系
O(1)<O(logn)<O(n)<O(nlogn)<O(n^2)<O(n^3)<O(2^n)<O(n!)<O(n^n)
python 内置类型性能分析
timeit: 通常用timeit模块来测试一小段代码的执行速度
list内置操作的时间复杂度:
转换list()<推导式[i for]<append()<insert<[ ]+[ ]
dict内置操作的时间复杂度:
因为以键值对形式存在,值唯一,大部分时间复杂度都为O(1)
copy和iteration为O(n)
注意:
1.同一个算法由于数据的不同,产生的效率也不相同
2.range(n) :在python3中不会自动生成列表
什么是算法:解决方法的一种方法和思想
算法的5大特性:
1.输入 2.输出 3.有穷性 4.确定性 5.可行性
什么是数据结构:用于描述数据元素之间的关系
算法与数据结构的关系:
用一些方法对这些数据结构的一系列操作,构成程序
程序 = 数据结构 + 算法
list,tuple,dict 相当于高级的数据结构
顺序表(基础的数据结构):
顺序表的两种形式: 顺序表的基本布局和外置的顺序表
基本存储单元:1字节=8位
整型--->需要四个存储单元--->32位
int a =100-->四个存储单元,地址连续
list=[100,200,300]---->申请12个存储空间(地址连续)
存储地址=初始地址*存储空间*下标(n-1)
为什么下标从0开始:第一个元素的存储地址等于初始地址
字符--->需要一个存储单元--->8位
list=[100,"a,b","abcde"]
存储过程:
1.将数据元素外置存储在相应的存储空间中
2.生成这个存储空间的存储地址
3.将外置的数据元素以储存地址的形式存放在原有的存储空间中