一、算法的引入
引入:如果a+b+c=1000,且a^2+b^2=c^2,(a,b,c为自然数),如何求出所有a,b,c可能的组合?
此时使用:枚举法【一种思想】
import time start=time.time() for a in range(1001): for b in range(1001): for c in range(1001): if a+b+c==1000 and a**2+b**2==c**2: print('a={},b={},c={}'.format(a,b,c)) end=time.time() print('花费时间:{:.2f}秒'.format(end-start))
结果显示:
a=0,b=500,c=500 a=200,b=375,c=425 a=375,b=200,c=425 a=500,b=0,c=500 花费时间:406.18秒
执行步骤:
T=1000*1000*1000*2 【最后的2是指:if和print】 其中1000是解决问题的规模,一般记为N 则T=N*N*N*2 则时间复杂度T(n)=n^3 (其中的2可以不计,相当于系数) 一般时间复杂度写为: O(n^3) 【大O表示法】
算法是:独立存在的一种解决问题的方法和思想
算法的五大特性:
(1)输入:算法具有0个或多个输入
(2)输出:算法至少有一个或多个输出
(3)有穷性:算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可接受的时间内完成
(4)确定性:算法中的每一步都有确定的含义。不会出现二义性
(5)可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成
二、时间复杂度
1、对上述的代码进行优化
【因为太耗时,需要406.18秒,下述代码对其进行优化】
import time start=time.time() for a in range(1001): for b in range(1001): c=1000-a-b if a**2+b**2==c**2: print('a={},b={},c={}'.format(a,b,c)) end=time.time() print('花费时间:{:.2f}秒'.format(end-start))
结果显示:
a=0,b=500,c=500 a=200,b=375,c=425 a=375,b=200,c=425 a=500,b=0,c=500 花费时间:4.37秒
执行步骤:
T=1000*1000*(1+max(1,0)) 【最后的1是指:c= max(1,0)是一个分支结构】 其中1000是解决问题的规模,一般记为N 则T=N*N*2 则时间复杂度T(n)=n^2 (其中的2可以不计,相当于系数) 一般时间复杂度写为: O(n^2) 【大O表示法】
2、时间复杂度的介绍
分析算法时,一般考虑:最优时间复杂度、最坏时间复杂度、平均时间复杂度
【一般我们为了关注算法的好坏,都是注重:最坏时间复杂度】
时间复杂度的几条基本计算规则:
(1)基本操作:即只有常数项,认为其时间复杂度为O(1)
(2)顺序结构:时间复杂度按加法进行计算
(3)循环结构:时间复杂度按乘法进行计算
(4)分支结构:时间复杂度取最大值
(5)判断一个算法的效率时,往往只需要关注操作数量的最高次项,其它次项和常数项可以忽略
(6)在没有特殊说明时,我们所分析的算法的时间复杂度都是指最坏时间复杂度
3、常见时间复杂度
4、python内置数据类型的时间复杂度
三、数据结构的引入
1、数据结构是指相互之间存在着一种或多种关系的数据元素的集合和该集合中数据元素之间的关系组成 。
2、常用的数据结构有:数组,栈,链表,队列,树,图,堆,散列表等。
3、算法与数据结构的区别:
数据结构只是静态的描述数据元素之间的关系
程序=数据结构+算法
总结:算法是为了解决实际问题而设计的,数据结构是算法需要处理的问题载体
4、抽象数据类(Abstract Data Type,ADT):指一个数学模型以及定义在此模型上的一组操作。即把数据类型和数据类型上的运算捆在一起,进行封装。
引入抽象数据类型的目的是把数据类型的表示和数据类型上运算的实现与这些数据类型和运算在程序中的引用隔开,使它们相互独立。