1.线性表概念
线性表是
N
个具有相同特征的结点
A
0
, A
1
, …, A
N-1
构成的集合。在这个集合中,除了A
0
和
A
N-1
外,每个元素都有唯一的前趋和后继。对于每个
A
i
,它的前驱是A
i-1
,它的后继是
A
i+1
。
A
0
只有后继没有前驱,
A
N-1
只有前驱没有后继。
•
表的术语:
•
N为表的大小
•
A
0
称为首结点, A
N-1
称为尾结点
•
空表:元素个数为零的表。
•
位置:元素A
i
在表中的位置为i
2.表的基本操作
•
create()
:创建一个空的线性表;
•
length()
:返回线性表的长度;
•
search(x)
:在线性表中搜索x是否出现,若出现则返回x的位置;
•
visit(i)
:返回线性表中第i个数据元素的值;
•
insert(i, x)
:在第i个位置插入一个元素,使线性表从(a0,a1,…ai-1,ai, …an-1)变成(a0,a1,…ai-1,x,ai, …an-1),参数i的合法取值范围是0到n;
•
remove(i)
:删除第i个位置的元素使线性表从(a0,a1,…ai-1,ai, ai+1 …an-1)变成(a0,a1,…ai-1, ai+1 , …an-1),参数i的合法取值范围是0到n-1;
•
clear()
:删除线性表中的所有数据元素;
•
traverse()
:遍历线性表,即按序访问线性表的每一数据元素。
代码:
class LinearList:
def __init__(self, maxSize=4):
self.capacity = maxSize # 最大容量
self.data = [None] * self.capacity #用列表存储线性表的元素
self.size = 0 #记录线性表的长度
def create(self, maxSize=4):
# create和__init__函数基本一致,所以可以直接用__init__代替
self.capacity = maxSize
self.data = [None] * self.capacity
self.size = 0
def search(self, x):
for i in range(self.size):
if self.data[i] == x:
return i
return -1 # 如果元素不存在,返回-1
def length(self):
return self.size
def clear(self):
self.size = 0
def insert(self, i, x):
if self.size == self.capacity:
self.double_space()
if 0 <= i <= self.size:
for j in range(self.size, i, -1):
self.data[j] = self.data[j - 1]
self.data[i] = x
self.size += 1
else:
raise IndexError("Invalid index")
def double_space(self):
self.capacity *= 2
new_data = [None] * self.capacity
for i in range(self.size):
new_data[i] = self.data[i]
self.data = new_data
def remove(self, i):
if 0 <= i < self.size:
for j in range(i, self.size - 1):
self.data[j] = self.data[j + 1]
self.data[self.size - 1] = None
self.size -= 1
else:
raise IndexError("Invalid index")
def visit(self, i):
if 0 <= i < self.size:
return self.data[i]
else:
raise IndexError("Index out of range")
def traverse(self):
for i in range(self.size):
print(self.data[i], end=' ')
print()
3.时间复杂度分析
•
length, visit和clear的实现与表中的元素个数无关,因此它们的时间复杂度是𝑂(1)
。
•
traverse()操作遍历整个数组中的所有元素,因此时间复杂度为
𝑂(𝑛)
。
•
create操作需要申请一块动态数组的空间,并设表为空。因此也是
𝑂(1)
的时间复杂度。
•
insert(),需要移动结点。当i等于n时,移动次数为0。当i等于0时,移动次数为n。
• 最好情况下的时间复杂度为
𝑂(1)
• 最坏情况下的时间复杂度为
𝑂(𝑛)
• 平均的时间复杂度:如果在每个位置上的插入都是等概率的,则插入算法的平均时间复杂度为n/2, 𝑂(𝑛)
4.总结
•
由于逻辑次序和物理次序的一致性使得定位访问的性能很好。
•
由于要保持逻辑次序和物理次序的一致性,顺序表在插入删除时需要移动大量的数据,性能不太理想。
因此顺序表比较适合静态的、经常做定位访问的线性表
•
python中list的底层实现大致与我们说的顺序线性表相同(虽然我们在代码演示中也使用了list,但我们并未使用list自带的append(), insert(), remove(),clear()等函数,而是自己写了一份含义基本相同的)