线性表
设计顺序表类为SqList,主要包含存放元素的data列表和表示实际元素个数的size属性。由于python语言属于弱类型语言,不必专门设计成像C++或java中的泛型类,在应用SqList时可以指定其元素为任意合法数据类型。
class SqList: # 顺序表类
def __init__(self): # 构造方法
self.initcapacity = 5 # 初始容量设为5
self.capacity = self.initcapacity # 容量设为初始容量
self.data = [None]*self.capacity # 设置顺序表的空间
self.size = 0 # 长度设为0
# 以下写线性表的基本运算算法
- 尽管Python中的列表data有自动扩展功能,但为了通用性,这里指定data容量为capacity,初始值为initcapacity,随着线性表的插入和删除,size是变化的。当size达到capacity时,再插入元素则会出现上溢出,为此将容量扩大为size的两倍。当删除元素时,若size小到一定程度时便缩小容量,从而实现顺序表的可扩展性。(可联想成:一个大盒子装着一个小盒子,当小盒子的东西变多时,小盒子变大了,大盒子就要变大,才能装得下)
线性表的基本运算——顺序表实现
插入和删除运算中可能涉及容量的更新,所以以下方法将data列表的容量改变为newcapacity
def resize(self, newcapacity): # 改变顺序表的容量为newcapacity
assert newcapacity >= 0 # 检测参数正确性的断言
olddata = self.data
self.data = [None]*newcapacity
self.capacity = newcapacity
for i in range(self.size):
self.data[i] = olddata[i]
- 说明:先让olddata指向data,为data重新分配一个容量为newcapacity的空间,再将olddata中的所有元素复制到data中,复制中所有元素的序号和长度size不变。原来的data空间会被系统自动释放。
1. 整体建立顺序表
从一个空顺序表开始,将一个列表的全部元素依次添加到顺序表的data列表末尾,当出现上溢出时按实际元素个数size的两倍扩大容量。
def CreateList(self, a): # 由数组a中的元素整体建立顺序表
for i in range(0,len(a)):
if self.size==self.capacity: # 出现上溢出时
self.resize(2*self.size) # 扩大容量
self.data[self.size]=a[i] # 添加元素a[i]
self.size += 1 # 添加一个元素后长度加1
2. 顺序表的基本运算算法
1. 将元素e添加到顺序表末尾 Add(e)
def Add(self, e):
if self.size==self.newcapacity: # 顺序表空间满时,让容量加倍
self.resize(2*self.size)
self.data[self.size]=e # 添加元素e
self.size+=1 # 长度加1
调用1次resize(),时间复杂度为O(n),但n次Add操作只需扩大一次data空间,所以平摊后的时间复杂度为O(1)
2. 求顺序表的长度 getsize()
def getsize(self):
return self.size;
3. 求序号i的元素值 getElem(i)
def __getitem__(self, i):
assert 0<=i<self.size # 当序号正确时,返回data[i]
return self.data[i]
4. 设置序号i的元素值 SetElem(i)
def __selfitem__(self, i, x):
assert 0<=i<self.size
self.data[i] = x
5. 求第一个值为e的元素序号 GetNo(e)
def GetNo(self, e):
i=0
while i<self.size and self.data[i]!=e:
i+=1
if i>=self.size:
return -1
else:
return i
时间复杂度为O(n)
6. 插入e作为第i个元素 Insert(i, e)
若参数正确(1<=i<=n),先将data[i…n-1]的每个元素均后移一个位置,腾出一个空位data[i]给e,最后长度size增1,。在插入元素时若出现上溢出,则按两倍size扩大容量。
def Insert(self, i, e):
assert 0<=i<=self.size # 检查i正确性的断言
if self.size==self.capacity: # 满时倍增容量
self.resize(2*self.size)
for j in range(self.size, i-1, -1):
self.data[j]=self.data[j-1]
self.data[i]=e
self.size+=1
7. 删除第i个数据元素 Delete(i)
def Delete(self, i):
asser 0<=i<=self.size-1
for j in range(i, slef.size-1):
self.data[j]=self.data[j-1] # 将data[i]之后的元素前移一位
self.size-=1
if self.capacity>self.initcapacity and self.size<=self.capacity/4:
self.resize(self.capacity//2) # 满足缩容条件则容量减半
8. 输出顺序表的所有元素 display()
def display(self):
for i in range(0, self.size):
print(self.data[i], end=' ')
print()