一、算法和数据结构
算法是解决问题的基本思路,数据结构是对基本数据类型的封装,是数据间的相互关系。
1. 算法的五大特性
a. 输入: 算法具有0个或多个输入
b. 输出: 算法至少有1个或多个输出
c.有穷性: 算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
d. 确定性:算法中的每一步都有确定的含义,不会出现二义性
e. 可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
算法与数据结构的区别
数据结构只是静态的描述了数据元素之间的关系。
高效的程序需要在数据结构的基础上设计和选择算法。
程序 = 数据结构 + 算法
总结:算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体
抽象数据类型(ADT)
抽象数据类型(Abstract Data Type 简称ADT)是指一个数学模型以及定义在此数学模型上的一组操作。抽象数据类型需要通过固有数据类型(高级编程语言中已实现的数据类型)来实现。抽象数据类型是与表示无关的数据类型,是一个数据模型及定义在该模型上的一组运算。
把数据和数据所支持的操作封装在一起,常见操作有增删改查排序。
ADT ADT-Name{
Data://数据说明
数据元素之间逻辑关系的描述
Operations://操作说明
Operation1://操作1,它通常可用C或C﹢﹢的函数原型来描述
Input:对输入数据的说明
Preconditions:执行本操作前系统应满足的状态//可看作初始条件
Process:对数据执行的操作
Output:对返回数据的说明
Postconditions:执行本操作后系统的状态//"系统"可看作某个数据结构
Operation2://操作2
……
}//ADT
二、Python 时间复杂度
1. 最坏时间复杂度
分析算法时,存在几种可能的考虑:
算法完成工作最少需要多少基本操作,即最优时间复杂度
算法完成工作最多需要多少基本操作,即最坏时间复杂度
算法完成工作平均需要多少基本操作,即平均时间复杂度
因此,我们主要关注算法的最坏情况,亦即最坏时间复杂度。
2. 时间复杂度的几条基本计算规则
-
基本操作,即只有常数项,认为其时间复杂度为O(1)
-
顺序结构,时间复杂度按加法进行计算
-
循环结构,时间复杂度按乘法进行计算
-
分支结构,时间复杂度取最大值
-
判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次要项和常数项可以忽略
-
在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
注:时间复杂度在程序中的示例见本博客最后。
3. 常见时间复杂度
4. 常见时间复杂度之间的关系
5. list内置操作的时间复杂度
5.dict内置操作的时间复杂度
三、timeit模块
timeit模块可以用来测试一小段Python代码的执行速度。
函数 | 功能 |
---|---|
timeit.Timer(stmt=‘要测试的函数’, setup=‘pass’, timer=) | $1600 |
timeit.Timer.timeit(number=1000000) | 返回执行number次代码的平均耗时 |
import timeit
def test1():
l1 = []
for i in range(100000):
l1.append(i)
///timeit模块的基本语句,from __main__ import test1从当前正在执行的函数导入test1
timer1=timeit.Timer("test1()",'from __main__ import test1')
print("l1.append(i):",timer1.timeit(1000))
补充:时间复杂度示例
问题:列出所有满足
a
+
b
+
c
=
1000
,
a
2
+
b
2
=
c
2
a+b+c=1000, a^2+b^2=c^2
a+b+c=1000,a2+b2=c2的a,b,c的值。
考虑用枚举法
方法1:三层循环,两层条件判断
a, b, c = [], [], []
import time
start_time = time.time()
def a_b_c():
start_time = time.time()
for a_1 in range(1001):
for b_1 in range(1001):
for c_1 in range(1001):
if a_1 + b_1 + c_1 == 1000 and a_1 ** 2 + b_1 ** 2 == c_1 ** 2:
a.append(a_1)
b.append(b_1)
c.append(c_1)
end_time = time.time()
time_delta = start_time - end_time
return a, b, c, time_delta
if __name__ == '__main__':
a, b, c, time_delta = a_b_c()
print(time_delta)
print('a{}\nb{}\nc{}'.format(a, b, c))
时间复杂度:
T
=
1000
∗
1000
∗
1000
∗
T=1000*1000*1000*
T=1000∗1000∗1000∗(4句话,不细分,不关心,不影响整体数量级)+4
抽象:
若改为(a+b+c=n),则时间复杂度为:
T
(
n
)
=
n
∗
n
∗
n
∗
4
=
=
n
3
∗
4
T(n)=n*n*n*4= =n^3*4
T(n)=n∗n∗n∗4==n3∗4
大O记法:
T
(
n
)
=
O
(
n
3
)
T(n)=O(n^3)
T(n)=O(n3)(理解为极限的同量级)
方法2:两层循环,一层条件判断
a, b, c = [], [], []
import time
start_time = time.time()
def a_b_c():
start_time = time.time()
for a_1 in range(1001):
for b_1 in range(1001):
c_1 = 1000 - a_1 - b_1
if a_1 ** 2 + b_1 ** 2 == c_1 ** 2:
a.append(a_1)
b.append(b_1)
c.append(c_1)
end_time = time.time()
time_delta = start_time - end_time
return a, b, c, time_delta
if __name__ == '__main__':
a, b, c, time_delta = a_b_c()
print(time_delta)
print('a{}\nb{}\nc{}'.format(a, b, c))
大O记法:
T
(
n
)
=
O
(
n
2
)
T(n)=O(n^2)
T(n)=O(n2)