顺序表
- 一组相同性质的元素,按照顺序的方式排列;位置可以通过计算获得。
分类
- 存相同的数据类型,占用相同的内存空间,可以使用基本布局
- 存不同的数据类型,占用不同的内存空间,可以元素外置,将地址存储在4个字节里顺序排列,但需要额外空间去存储元素。例如:list
结构
一个顺序表的完整信息包括两部分,一部分是表中的元素集合,另一部分是表头信息,包括元素存储区的容量和当前表中已有的元素个数。
两种实现方式
- 一体式结构:存储表信息的单元与元素存储区以连续的方式安排在一块存储区里,两部分数据的整体形成一个完整的顺序表对象。
- 为分离式结构:表对象里只保存与整个表有关的信息(容量+元素个数+元素位置信息),实际数据元素存放在另一个独立的元素存储区里,通过链接与基本表对象关联。
顺序表的操作
替换
- 一体式结构:只能整体搬迁,即整个顺序表对象都需要改变。
- 分离式结构:只需将表信息区中的数据区链接地址更新。
扩充
- 为了扩充空间才去替换,和替换的思路一样
扩充的两种策略
- 增加固定数目的存储位置
- 每次扩充容量加倍
增加元素
- 尾端加入元素,时间复杂度为O(1)
- 非保序的加入元素,插入元素位置上的原有元素放在最后(不常见),时间复杂度为O(1)
- 保序的元素加入(元素依次向后移),时间复杂度为O(n)
删除元素
- 删除表尾元素,时间复杂度为O(1)
- 非保序的元素删除(不关注),时间复杂度为O(1)
- 保序的元素删除(后面元素依次向上移),时间复杂度为O(n)
Python中的顺序表
- list和tuple两种类型采用了顺序表的实现技术
list实现技术
- 检索
基于下标(位置)的高效元素访问和更新,一步计算就可以获得位置,时间复杂度应该是O(1); - 添加和删除
采用分离式技术实现的动态顺序表,所以任意加入和删除元素,表对象不变。 - 扩充方式
(1)在建立空表(或者很小的表)时,系统分配一块能容纳8个元素的存储区,采取元素外置的方式。
(2)当元素<50000个时,换一块4倍大的存储区
(3)当元素>50000个时,加一倍大的存储区
疑难问题
Q1:为什么位置要从0开始?
代表的是位置的偏移量,不是绝对位置,是相对最初的元素的位置。
Q2: 为什么需要提前预估容量?
因为数据必须连续存储,多出的数据无法连续存储。
Q3:扩充和增加的不同?
扩充的是空间,当顺序表空间使用完后,需要额外向系统申请预留空间;增加的是元素,在可使用的空间内增加新的元素。