Python数据结构与算法1—顺序表和链表

引言

题目:a**2 + b**2 = c**2,a+b+c=1000,求解a,b,c

方法一
import time 

start = time.time()
for a in range(0, 1001):
    for b in range(0, 1001):
        for c in range(0, 1001):
            if a + b + c == 1000 and a**2 + b**2 == c**2:
                print("a:{0},b:{1}, c:{2}".format(a, b, c))
end = time.time()
print(end - start)

# 方法二
import time 

start = time.time()
for a in range(0, 1001):
    for b in range(0, 1001):
        # 优化之处
        c = 1000 - a - b
        if  a**2 + b**2 == c**2:
            print("a:{0},b:{1}, c:{2}".format(a, b, c))
end = time.time()
print(end - start)

时间复杂度O(n)

基础

通过运算的时间来进行度量,用n来进行表示。有几种情况:

  • 最优时间复杂度
  • 最坏时间复杂度
  • 平均复杂度

常见的计算规则:

  • 顺序:累加结构计算
  • 循环:乘法结构计算
  • 分支:取最大值

一般取的是最坏时间复杂度,考虑最坏的情况,同时忽略常数项

常见的时间复杂度

消耗的时间大小关系:

timeit模块

主要功能是进行测试

# 比较几种列表生成式
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]
        li += [i]
        
def t3():
    li = [i for i in range(10000)]
    
def t4():
    li = []
    for i in range(10000):
        li.insert(0, i)
    
time1 = Timer("t1()", "from __main__ import t1")
print("append:", time1.timeit(10000))

time2 = Timer("t2()", "from __main__ import t2")
print("+:", time2.timeit(10000))

time3 = Timer("t3()", "from __main__ import t3")
print("[]:", time3.timeit(10000))

time4 = Timer("t4()", "from __main__ import t4")
print("insert:", time4.timeit(10000))

列表和字典的时间复杂度

列表

操作 复杂度
index [] 0(1)
append 0(1)
pop() 0(1)
pop(i) O(n)
insert() O(n)
sort() O(nlogn)

字典

操作 复杂度
copy() O(n)
get,set,delete,contains,iteration O(1)

数据结构

数据结构是指数据对象中数据元素之间的关系,在Python中内置的数据结构,比如列表、字典、元组等,扩展结构:栈、队列等。
程序 = 数据结构 +算法

常见的操作:

  • 插入
  • 删除
  • 修改
  • 查找
  • 排序

顺序表

存储方式

数据本身是连续存储,每个元素占据固定大小的单元,元素下标是逻辑地址,包含:数据区+表头信息,两种存储方式:

  • 一体式结构:表头信息和数据区连在一起,表头区包含容量和元素个数
  • 分离式结构:表头信息和数据区分开存放,通过表头区的地址单元去指向数据区

扩充策略

  • 每次固定的扩充数目:线性扩充,节省空间。扩充频繁,操作频繁
  • 每次扩充容量加倍:减少扩充执行次数,浪费资源。以空间换取时间

链表

链表由来

顺序表的构建需要预先知道数据大小来申请连续的存储空间;再进行扩充的时候需要进行数据的迁移,很不方便。链表能够充分地利用计算机的存储空间,实现灵活的内存动态管理。

线性表包含顺序表和链表。在链表中,元素与元素之间通过链接构造起来的一系列存储结构中,每个节点(存储单元)中存放下一个节点的位置信息。。节点中包含:数据取 + 链接区(指针区)。最后一个没有指针区

单向链表

单向链表包含数据区和链接区。链接指向下一个链接表中的节点。最后一个节点指向空值(一竖一横表示)。

主要的操作是:

  • is_empty()
  • length()
  • travel()
  • add(item)
  • append()
  • insert()
  • remove()
  • search()

在Python的中,a是个地址,保存的不是10,地址指向10。

顺序表和链表对比

顺序表

  • 随机读取数据
  • 查找很快,耗时主要是在拷贝和覆盖
  • 存储空间必须是连续的

链表

  • 增加了节点地指针区域,空间开销大,对存储空间的使用更加灵活
  • 耗时主要是体现在:遍历查找
  • 只记录头结点,如果想找到其他节点,必须通过遍历的方式去寻找
  • 存储空间不是连续的:数据区+指针区,对离散空间能够充分利用

时间复杂度对比

操作 链表 顺序表
访问元素 O(n) O(1)
头部 O(1) O(n)
尾部 O(n) O(1)
中间 O(n) O(n)

为什么链表的时间复杂度增加,还要使用链表?

  • 链表存储数据时不使用连续空间,如果内存中没有连续的空间用来存储数据,那么不能用顺序表只能用链表;
  • 链表对离散空间利用率高
    最好的Python数据结构与算法
    Python数据结构与算法1—顺序表和链表_第1张图片
    图片发自App

你可能感兴趣的:(Python数据结构与算法1—顺序表和链表)