人工智能
- python,大数据,机器学习,深度学习,计算机视觉
- 三、python算法篇(二)顺序表
- 顺序表的两种存储形式
- (1)基本顺序表
- (2)元素外围顺序表
- 顺序表的 ==一体式结构== 与 ==分离式结构==
- 顺序表的替换与扩充
- 顺序表的插入与删除元素
- (1)插入
- 删除
- 其他知识点
python,大数据,机器学习,深度学习,计算机视觉
三、python算法篇(二)顺序表
顺序表的两种存储形式
(1)基本顺序表
顺序表:数据在内存按顺序存放的表。相同类型的元素采用这种数据结构存放,方便取用。
比如列表li = [7, 2100, 390]按照顺序存放,显示存的都是相同类型int型元素,若知道元素“7”的物理地址是0x01,由于int型占4Byte,则元素“2100”的物理地址是0x01 + 4 = 0x05, 元素“390”的物理地址是0x01 + 42 = 0x09。
也就是说,给你元素“7”的物理地址0x01,去取元素“390”,不用挨个遍历,直接访问0x01 + 42 = 0x09这个物理地址即可取到元素“390”了。
结论:顺序表中,某一元素的物理地址 = 存储区的起始地址 + 存储单元大小 * 该元素下标(即该元素逻辑地址),访问元素时无需遍历,通过计算便可获得对应地址,其时间复杂度为O(1)。
注释:
物理地址(实际内存地址)
逻辑地址(就是元素下标,可看成虚拟地址)
(2)元素外围顺序表
如图,左边定义的列表Li是前面讲的基本顺序表,右边定义的列表li是元素外围顺序表。
区别:基本顺序表存的是相同类型的元素
而元素外围顺序表存的是不同类型的元素。所以它先在内存中随机生成地址存元素值,再开辟一连续的内存空间用来专门指向(存储)目标地址。
顺序表的 一体式结构 与 分离式结构
list li[8]
li = [1328, 693, 2529, 154]
同Java一样,先定义一个列表(数组)li,总共8个元素,初始化赋值了前4个值。
所以存储结构设计的时候,加上“表头信息”:容量、元素个数。这样如果存满了,再存元素就能控制不让添加了,返回error。
下图左边的设计是一体式结构,右边的设计是分离式结构。
左边一体式:假定Li初始地址是0x15
右边分离式:假定Li初始地址是0x111
哪个设计好?
为了考虑以后数据的动态变化,右边的分离式结构较好一些,较常用。分析下:
拿上面的图来说,在Li=[200, 390, 78]基础上(初始只给分配了最大存4个元素的空间),重新定义Li = [200, 390, 78, 300, 500, 600],所以重新开辟一块地址:
(1)若采用一体式:
此时列表Li的初始位置0x15已经变为0x1000,(这里0x1000是内存随机生成的地址)
(2)若采用分离式:
此时列表Li的初始位置依然还是0x111,没有变
所以采用分离式,数据动态变化时,初始地址不会随之改变。
顺序表的替换与扩充
还拿上面的例子,如下图:
Li = [200, 390, 78]在存储空间里分配时预留了空闲空间0x35~0x39以便后续扩展用,那么我们在扩充时把它使用了,我们还要不要再预留出空闲空间以便再扩展用?再预留分配多少空闲空间?
方案有两种
(1)我们可以还预留4Byte的空闲空间(1个int型的空间大小),即0x39~0x43,。若再占用再预留4Byte的空闲空间(1个int型的空间大小)…
每次都预留固定数目4Byte的空闲空间。
(2)我们可以预留42=8Byte的空闲空间(2个int型的空间大小),即0x39~0x47。若再占用再预留82=16Byte的空闲空间(4个int型的空间大小),乃至(8个int)(16个int)…
每次都加倍扩充/预留空闲空间。
顺序表的插入与删除元素
(1)插入
如图,三种不同方式地插入新元素111
a.直接在表尾端插入。
b.在下标1位置插入新元素111,而将下标1元素693放到了表尾。这是不用保持原来元素相对顺序不变的插入方式------ 非保序插入
c.在下标1位置插入新元素111,其以及其后的元素依次向后顺移!这是保持原来元素相对顺序不变的插入方式!------ 保序插入(稳住,别乱!嘎嘎)
注:非保序插入现实中不实用,故不常用。
结论:
a.尾端插入元素,时间复杂度为O(1)
b.非保序的插入元素(不常见),时间复杂度为O(1)
c.保序的元素插入,时间复杂度为O(n)
删除
删除同理,来不及解释了,快上车!
其他知识点