Python实现数据结构和算法(一)

数据结构和算法

  • 广义:数据结构就是一组数据的存储结构,而算法就是操作数据的一组方法

算法的引入

算法就相当于军师在排兵布阵

  • 如果a + b + c = 1000,并且 a的平方+b的平方 = c的平方,如何求出所有的a,b,c的可能组合?
# 枚举法--暴力破解
import  time
start_time = time.time()
# 循环嵌套 
for a in range(0,1001):
    for b in range(0,1001):
        for c in range(0,1001):
            if a**2 + b**2 == c**2 and a + b + c == 1000:
                print('a,b,c:%d,%d,%d'%(a,b,c))# 格式化的方式
end_time = time.time()
print('times:%f'%(end_time-start_time))
print('end')

运行时间会很长,实际上这就是算法。

算法的概念

  • 算法是计算及处理信息的本质,因为计算机程序本质上是一个算法来告诉计算机确切的步骤来执行一个指定的任务。一般地,当算法在处理信息是,会从输入设备或者数据的存储地址读取数据,把结果写入输出设备或者某个存储地址供以后再调用。
  • 算法是独立存在的一种解决问题的方法和思想
  • i对于算法而言,实现的语言并不重要,重要的是思想

算法的特性

  • 输入:算法具有0个或者多个的输入
  • 输出:算法至少有1个或者多个的输出
  • 有穷性:算法在有限的步骤之后会自动结束而不会无限循环,并且每一个步骤可以在可以接受的事件内完成
  • 确定性:算法中的每一步都有确定的含义,不会出现二义性。
  • 可行性:算法的每一步都是可行的,也就是说每一步都能够执行有限的次数完成。
    根据以上的问题,再进行优化:
import time
start_time = time.time()
for a in range(0,1001):
	for b in range(0,1001-a):
		c = 1000- a - b
		print('a,b,c:%d,%d,%d'%(a,b,c))
end_time = time.time()
print('times:%f'%(end_time- start_time))
print('end')

运行结果:

a,b,c:0,500,500
a,b,c:200,375,425
a,b,c:375,200,425
a,b,c:500,0,500
times:0.748054
end

简化的思想:因为a+b+c = 1000,所以在循环嵌套的第一层,确定了a的值,所以可以确定b=1000-a,第二层循环确定了b = 1000-a,而c=1000-a-b,所以c的值就确定了,这样代码就会很便捷,运行时间变少。

  • 而测试并不是绝对可靠的
    测试的时间受数据的规模的影响
    测试的时间受测试的环境的影响

O复杂度表示方法

算法的执行效率就是算法代码的执行时间
虽然每台机器的执行总时间不同,但是每台电脑的执行的基本运算大体是相同的。
如下:

for i in range(2):
	for i in range(3):
		print(i,j) 
0 0
0 1
0 2
1 0
1 1
1 2

由此可见i和j是一个相乘的关系。
再回到上面的代码中

for a in range(0,1001):
    for b in range(0,1001):
        for c in range(0,1001):
            if a**2 + b**2 == c**2 and a + b + c == 1000:
                print('a,b,c:%d,%d,%d'%(a,b,c))# 格式化的方式
# a执行1000次,b执行1000次,c也执行1000次,if语句执行2次
# 所以时间T(n) = 1000 * 1000 * 1000 * 2
# 如果将1000换成n则时间T(n) = n^3 *2
# n^3*2看成是f(n)
# T(n) = f(n)*2
# T(n) = O(f(n))

所有代码的执行时间T(n)与每行代码的执行次数n成正比
T(n) = O(f(n))
公式中的低阶、常量、系数三部分并不能左右增长趋势,所以都可以忽略,只需要记录一个最大的量级就可以了

时间复杂度分析

  • 只关注循环执行次数最多的一段代码
def cal(n):
	sum = 0
	i = 1
	for i in range(n + 1):
		sum += i
		i += 1
	return sum
# T(n) = O(n)
  • 加法法则:总复杂度等于量级最大的那段代码的复杂度
def cal(n):
	sum = 0
	i = 1
	for i in range(100):
		sum += i
	for i in range(n+1):
		sum += i
		i+= 1
	for i in range(n+1):
		for j in range(n +1):
			pass
# T(n) = max(O(1) + O(n) + O(n^2)) = O(n^2)

综合三段代码的时间复杂度,得出整段代码的时间复杂度T(n) = f(n^2),所以总的时间复杂度就等于量级最大的那段代码的时间复杂度。

最坏的时间复杂度

在分析算法的时候,存在几种可能的考虑:

  • 最优时间复杂度–最少需要多少基本操作
  • 最坏时间复杂度–最多需要多少基本操作
  • 平均时间复杂度–平均需要多少基本操作
# 如果按从小到大开始排列
li1 = [1,2,3,4,5]# T(n) = O(1) 最优的时间复杂度
li2 = [5,4,3,2,1]# T(n) = O(n) 最坏的时间复杂度
常见时间复杂度

Python实现数据结构和算法(一)_第1张图片
Python实现数据结构和算法(一)_第2张图片

Python内置类型性能分析

li =[]
li.append()
li.insert()

timeit模块
timeit模块用来测试一小段Python代码的执行速度

class timeit.Timer(stmt = ‘pass’,setup = ‘pass’,timer = )
Timer 是测量小段代码执行速度的类
stmt参数是要测试的代码语句(statment);
setup参数是运行代码时需要的设置
timer参数是一个定时器函数,和平台有关
timeit.Timer.timeit(number = 1000000)
Timer类中测试语句执行速度的对象方法。
list的操作测试

def ts1():
	l = []
	for i in range(1000):
		l = l + [i]
		
def ts2():
	l = []
	for i in range(1000):
		l.append(i)
		
def ts3():
	l = [i for i in range(1000)]
	
def ts4():
	l = list(range(1000))
	
def ts5():
	l = []
	for i in range(1000)
		l.insert(0,i)
from timeit import Timer

t1 = Timer("ts1()","from __main__ import ts1")
print("add",t1.timeit(number = 1000))
t2 = Timer("ts2()","from __main__ import ts2")
print("append",t2.timeit(number = 1000))
t3 = Timer("ts3()","from __main__ import ts3")
print("list derivation",t3.timeit(number = 1000))
t4 = Timer("ts4()","from __main__ import ts4")
print("list range",t4.timeit(number = 1000))
t5 = Timer("ts5()","from __main__ import ts5")
print("list insert",t5.timeit(number = 1000))

数据结构

那么我们如何用Python中的类型来保存一个班的学生信息呢?

"""
第一种方式
{
	'zhangsan':{
	'age':18,
	'address':'css'
		}
}
第二种方式
[
	('zhangsan',18,'dff'),
	('lisi',17,'der'),
	('zhaowu',19,'dfg')
]
第三种方式
[
	{
		'name':'zhangsan',
		'age':18,
		'address':'hkl'
    }
]
"""

算法和数据结构的区别

数据结构是静态的描述了数据元素之间的关系
高效的程序需要在数据结构的基础上设计和选择算法
程序 = 数据结构 + 算法
算法是为了解决实际问题而进行设计的,数据结构是算法需要处理的问题载体。

抽象数据类型

抽象数据类型的含义是指一个数学模型以及定义在此数学模型上的一组操作,就是把数据类型和数据类型上的运算捆绑在一起,进行封装

"""
第一种方式
{
	'zhangsan':{
	'age':18,
	'address':'afd'
		}
}
第二种方式
[
	('zhangsan',18,'dff'),
	('lisi',17,'der'),
	('zhaowu',19,'dfg')
]
第三种方式
[
	{
		'name':'zhangsan',
		'age':'18',
		'address':'hkl'
    }
]
"""
class stu(object):
	def add(self):
		pass
	def pop(self):
		pass
	def sort(self):
		pass
	def modify(self):
		pass

上述代码中:
class类相当于一个模型,而def这些定义的函数,比如add pop sort modify就相当于模型上的操作

总结:

Python实现数据结构和算法(一)_第3张图片

你可能感兴趣的:(数据结构,python)