线性表——Python的list(2-3)

Python的list

(1)list是一种线性结构,可看作线性表的一种实现。

重要特点:基于下标(位置)的元素访问和更新操作,复杂性为O(1),允许任意加入元素(不会出现“表满”而无法加入新元素的情况),而且在不断加入元素的过程中,表对象标识( id(...). 的值)不变

(2)list实现的基本约束和解决方案

要求O(1)的元素访问并维持元素的顺序,只能采用连续表技术,元素保存在一块连续存储区

要能容纳任意多元素,必须在元素个数将要超出存储区容量时换一块更大存储区。要想在替换存储时id 不变,只能采用分离式实现

(3)采用上述实现方法,自然的后果:

一般的元素加入/删除都需要O(n) 时间,需要移动许多元素。

如果要求加入元素时存储区已满,就需要换一块存储, 把原有元素拷贝过去(优化: 可以在拷贝过程中完成元素加入)

list 的逐步建立

(1)较大的list ,通常是通过不断加入元素逐步建立起来的。

加入一个元素,一般情况需要0(m) 时间

建立起n个元素的表,就需要O(m2) 时间

最好的情况:尾端加入,不需要移动元素

(2)注意,不断在尾端加入元素的过程中可能出现两种情况

如果存储区不满,O(1) 时间可以完成操作

如果存储区满,就需要O(u) 时间(换存储区,拷贝元素)

最坏情况复杂性一定是O(m), 但能否得到较好的平均时间?

(3)情况:如果高开销操作很少出现,平均操作代价可能比较低。

考虑每次替换存储区增加10 个空位,10 次加入才有一次高代价

但注意,(1/10) O(n) = O(n),平均复杂性的性质没变。

(4)list里元素越多(表越长),换一次存储区的代价也越高

要想平均结果较好,随着表长度增加,换存储区的频度应降低

一种可能做法:每次换存储区时,容量加倍

(5)计算:假设表的初始容量为1, 不断增长到长度为20_{20} \approx 100,000

加入操作共做了大约10_{6}

替换存储时的元素拷贝:

1+2+4+8+...+2_{19} ≈ 2_{20}

总开销大约为2*2_{20}, 是O(m) 的量级,平均O(1)

(6)一次高开销操作后,保证有很多次低开销操作,称为“分期付款式”的常量复杂性(平摊式的复杂性)

Python的list 采用这种设计,因此lst.insert(en(st),x) 比一般位置加入的效率高,等价写法Istappend(x) 。 如合适,应优先使用

list的操作

(1)Python list的实际实现策略

建立空list 时分配可以容纳8个元素的存储区

元素区满时加入:换一块4倍大的存储区;但在表已经比较大时就会改变策略,换存储区时规模加倍

效果:通过尾端加入元素,操作的平均复杂性是0(1)

(2)其他操作的性质由连续表的实现方式确定

所有序列的共性操作,复杂性由操作中需要考察的元素个数确定,其中len() 是O(1) 操作

元素访问和赋值,尾端加入和尾端(切片)删除是0(1) 操作

一般元素加入,切片替换,切片删除,表拼接( extend)等都是O(n)操作。pop操作默认情况是尾端删除返回,为O(1), 一般情

况(指定非尾端位置)为O(n)

(3)Python没提供检查一个list 的当前存储块容量的操作

发布了113 篇原创文章 · 获赞 94 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_44762986/article/details/104573648
今日推荐