思维导图
修改 SeqList 类,实现自动扩容/缩容功能:
- 当插入元素时,若当前 size == capacity,将容量扩容为原来的 1.5 倍(取整)
代码
#自动扩容
def expand(self):
self.data = self.data + [None]*self.capacity
self.capacity = int(self.capacity * 1.5)
#判满
def is_full(self):
#如果为满则执行扩容
if self.size == self.capacity:
SeqList.expand(self)
#顺序表的增加(尾插)
def add_tail(self,value):
# 判断容量是否已满
SeqList.is_full(self)
self.data[self.size] = value
# 已存储的元素个数加1
self.size += 1
#任意位置插入数据
def add_index(self,index,value):
# 判断容量是否已满
self.is_full()
if index > self.size or index < 0:
print("插入失败")
return
else:
for i in range(self.size-1,index-1,-1):
self.data[i+1] = self.data[i]
self.data[index] = value
self.size += 1
2.当删除元素后,若 size < capacity//4 且 capacity > 10,将容量缩容为原来的 一半
代码
#自动缩容
def shrink(self):
#判断条件
if self.size < self.capacity//4 and self.capacity>10:
#备份原表数据
data2 = self.data
#减小容量
self.capacity = self.capacity//2
#创建新表存储数据
self.data = [None]*self.capacity
#数据迁移
for i in range(self.capacity):
self.data[i] = data2[i]
#任意位置删除数据
def remove_index(self,index):
# 判断是否为空
if self.is_empty() or index >= self.size or index < 0:
print("删除失败")
return
else:
for i in range(index,self.size):
self.data[i] = self.data[i+1]
self.size -= 1
#判断是否需要缩容
self.shrink()
3.添加 get_capacity() 方法返回当前实际容量
代码
#返回实际容量
def get_capacity(self):
print(f"当前实际容量为{self.capacity}")
4】高效合并有序顺序表
题目:
实现 merge_sorted 方法,合并两个升序排列的 SeqList:
- 输入:另一个 SeqList 对象(假设已按升序排列)
- 输出:合并后的新 SeqList(保持升序)
- 要求直接修改原表,不创建新数组
代码
def merge_sorted(self, seclist):
# 扩容以容纳 seclist 的数据
if self.capacity < self.size + seclist.size:
while self.capacity < self.size + seclist.size:
self.expand() # 使用已有的 expand 方法扩容
# 将 seclist 的数据复制到当前表的末尾
for i in range(seclist.size):
self.data[self.size] = seclist.data[i]
self.size += 1
# 使用插入排序对合并后的数据进行排序
for i in range(1, self.size):
key = self.data[i]
j = i - 1
while j >= 0 and self.data[j] > key:
self.data[j + 1] = self.data[j]
j -= 1
self.data[j + 1] = key
list1 = SeqList()
list1.add_tail(1)
list1.add_tail(3)
list1.add_tail(5)
list2 = SeqList()
list2.add_tail(2)
list2.add_tail(4)
list2.add_tail(6)
list1.show()
list1.merge_sorted(list2)
list1.show()
5】独立写一个顺序表 完成对学生的存储。
class Student:
def __init__(self, sid, name, age):
self.sid = sid # 学号
self.name = name # 姓名
self.age = age # 年龄
# 重写相等判断,以学号作为唯一标识
def __eq__(self, other):
if isinstance(other, Student):
return self.sid == other.sid
return False
# 方便打印输出
def __str__(self):
return f"学号:{self.sid:0>4}\t姓名:{self.name}\t年龄:{self.age}"
class StudentSeqList:
def __init__(self, capacity=5):
self.capacity = capacity # 容量
self.data = [None] * self.capacity # 存储容器
self.size = 0 # 元素个数
# 自动扩容方法
def expand(self):
new_capacity = self.capacity * 2 # 扩容双倍
new_data = [None] * new_capacity
# 迁移原有数据
for i in range(self.size):
new_data[i] = self.data[i]
self.data = new_data
self.capacity = new_capacity
print(f"触发扩容,新容量:{new_capacity}")
# 判断是否已满
def is_full(self):
return self.size == self.capacity
# 判断是否为空
def is_empty(self):
return self.size == 0
# 尾插法(添加学生)
def add_tail(self, student):
# 自动扩容判断
if self.is_full():
self.expand()
self.data[self.size] = student
self.size += 1
# 遍历显示
def show(self):
if self.is_empty():
print("(空列表)")
return
print("\n", "-" * 30)
print(f"当前存储元素:{self.size}/{self.capacity}")
for i in range(self.size):
print(f"{i + 1}. {self.data[i]}")
print("-" * 30, "\n")
# 指定位置插入
def insert(self, index, student):
if index < 0 or index > self.size:
print("插入失败:无效的索引位置")
return
if self.is_full():
self.expand()
# 元素后移
for i in range(self.size, index, -1):
self.data[i] = self.data[i - 1]
self.data[index] = student
self.size += 1
# 按索引删除
def remove_index(self, index):
if index < 0 or index >= self.size:
print("删除失败:无效的索引")
return
# 元素前移
for i in range(index, self.size - 1):
self.data[i] = self.data[i + 1]
self.size -= 1
self.data[self.size] = None # 清空最后一个元素的引用
# 按学号查找(返回第一个匹配的索引)
def find(self, sid):
for i in range(self.size):
if self.data[i].sid == sid:
return i
return -1
# 按学号删除
def remove_sid(self, sid):
index = self.find(sid)
if index == -1:
print("删除失败:学号不存在")
return
self.remove_index(index)
# 学生信息修改(保持学号不变)
def update(self, sid, new_name, new_age):
index = self.find(sid)
if index == -1:
print("修改失败:学号不存在")
return
self.data[index].name = new_name
self.data[index].age = new_age
# 去重处理(保留最早出现的记录)
def distinct(self):
seen = set() # 已出现学号集合
keep_index = 0 # 有效元素存放指针
for i in range(self.size):
current_sid = self.data[i].sid
if current_sid not in seen:
seen.add(current_sid)
# 保留元素前移
if i != keep_index:
self.data[keep_index] = self.data[i]
keep_index += 1
# 清理后续空间并更新size
for i in range(keep_index, self.size):
self.data[i] = None
self.size = keep_index
# 测试代码
if __name__ == "__main__":
# 创建顺序表(初始容量设为3)
student_list = StudentSeqList(3)
# 添加基础数据
student_list.add_tail(Student(1001, "张三", 18))
student_list.add_tail(Student(1002, "李四", 19))
student_list.add_tail(Student(1003, "王五", 20))
student_list.show() # 显示3条
student_list.add_tail(Student(1004, "赵六", 21)) # 触发扩容
student_list.show() # 容量变为6
# 插入重复学号测试
student_list.insert(2, Student(1002, "克隆人", 99))
student_list.show()
student_list.distinct() # 去重处理
student_list.show()
# 修改测试
student_list.update(1003, "王五改", 21)
student_list.show()
# 删除测试
student_list.remove_sid(1004)
student_list.show()