综合实验1 学生成绩录入
实验目的:深入理解顺序表的存储结构,熟练掌握顺序表的基本操作。
实验背景:由于顺序表中存储数据的空间是连续的,因此表中任意一个元素都可被随机访问。在实际的信息管理应用中,顺序表更适合处理插入和删除操作较少的数据,以学生考试成绩的数据为例,当成绩被确定后,一般只会执行查询操作,而几乎不会涉及插入或删除操作,因此顺序表通常被用于处理此类数据。请借助于顺序表处理表2-18中软件学院某班部分学生在大学第一个学期的期末考试成绩。
实验内容:创建文件ex030502_01.py,并在其中编写学生成绩录入程序,具体如下。
(1)将表2-18中学生姓名、高数成绩及英语成绩依次输入顺序表中。
(2)对上述学生按高数成绩排序。
(3)对上述学生按英语成绩排序。
(4)删除当前顺序表中第三位学生的所有信息。
实验提示:
在每次输入信息时,可将姓名及成绩拆分为多个字符串同时输入。
class seq():
#初始化顺序表函数
def __init__(self):
self.name = []
self.math = []
self.eng = []
def createstudenttable(self):
print("请输入元素后按回车键确认,若想结束请输入#")
element = input("请输入姓名,高数成绩,英语成绩并用空格隔开:")
while element !="#":
name = element.split(" ")[0]
math = element.split(" ")[1]
eng = element.split(" ")[2]
self.name.append(name)
self.math.append(math)
self.eng.append(eng)
element = input("请输入姓名,高数成绩,英语成绩并用空格隔开:")
#按高数成绩排序
def sortmath(self):
for i in range(len(self.name)):
for j in range(i + 1, len(self.name)):
if self.math[i] > self.math[j]:
a = self.math[i]
self.math[i] = self.math[j]
self.math[j] = a
a = self.name[i]
self.name[i] = self.name[j]
self.name[j] = a
a = self.eng[i]
self.eng[i] = self.eng[j]
self.eng[j] = a
print(self.name,self.math)
#删除顺序表中第三位
def DeleteElement(self):
self.name.remove(self.name[2])
self.math.remove(self.math[2])
self.eng.remove(self.eng[2])
print(self.name)
s = seq()
s.createstudenttable()
#s.sortmath()
s.DeleteElement()
综合实验2 单链表的就地转置
实验目的:深入理解单链表的存储结构,熟练掌握单链表的基本操作。
实验背景:由于单链表采用的是链式存储结构,因此我们不需要通过移动元素来实现数据的插入及删除操作,只需要通过修改表中结点的指针,即可实现对链表的修改。所以在实际应用中,我们经常使用单链表来处理插入和删除操作较多的数据。某购物平台中的商品每天是在不断更新的,若图2-37是某一时刻我们按价格升序浏览苹果的结果,假定上述结果存储在单链表中,当我们想按价格的降序来查看这一结果时,该如何实现?这时我们可以通过对存储上述结果的单链表进行转置来实现。
实验内容:创建文件ex030502_02.py,并在其中编写单链表就地转置的程序,具体如下。
(1)创建单链表A,并将上述苹果的价格作为参数创建相应结点,并逐一链入A中。
(2)从第二个结点开始直至最后一个结点,将其逐一通过头插法插入到第一个结点之前,最后完成单链表的转置。
(3)输出就地转置后的单链表A。
实验提示:
(1)在遍历过程中,可使用一个指针指向A中第一个结点的位置。
(2)借助头插法移动结点的过程中,操作指针时应格外小心,否则容易发生断链的情况。
class Node():
def __init__(self, name,price):
self.name = name
self.price = price
self.next = None
class seq():
def __init__(self):
self.head = Node(None,None)
def create(self):
cNode = self.head
element = input("请输入苹果种类,价格用空格分开")
while element !="#":
name = element.split(" ")[0]
price = element.split(" ")[1]
nNode = Node(name,price)
cNode.next = nNode
cNode = cNode.next
element = input("请输入苹果种类,价格用空格分开")
def reverse(self):
cNode = self.head
if cNode.next == None or cNode==None: # 若链表为空或者仅一个数就直接返回
return cNode
pre = Node(None,None)
#这个理论简单来说,举例12345-21345-32145-43215-54321
while(cNode != None):
nNode = cNode.next # 保存第二个节点
cNode.next = pre # 第二个节点为pre
pre = cNode
cNode = nNode # 第二个节点为赋值为第一个节点
return pre
def trval(self):
"""
遍历单链表
:return:
"""
curr = self.head.next
while curr is not None:
print(curr.name, end=",")
curr = curr.next
print(" ")
s = seq()
s.create()
s.reverse()
s.trval()
综合实验3 每日快递
实验目的:深入理解循环单链表的存储结构,熟练掌握循环单链表的基本操作。
实验背景:瑶湖快递的快递员张小明每日负责N市高新技术开发区中10个居民小区的快递派送任务,张小明会在每天上午9点和下午2点分别进行两次派送,图2-38所示为张小明每日的派送路线。快递公司规定,在派送过程中,快递员还应接收小区内已预定寄出的快递,若某小区需要派送的快递个数和接收的快递个数均为零,快递员则不需要前往该小区,而是直接前往下一小区进行派送。每日派送结束后,公司对每位快递员去过的小区数目及收寄快递的数量进行清点。假设表2-19所示为张小明今日的工作记录,请借助于循环单链表来实现公司对张小明当日派送任务的清点。
实验内容:创建文件ex030502_03.py,并在其中编写快递派送清算程序,具体如下。
(1)创建循环单链表A,并将小区编号作为参数创建相应结点,并依次链入循环单链表A中。
(2)通过扫描A,记录下快递员走过的小区个数,并将派送快递的总个数、接收快递的总个数存入当前结点的数据域中。
(3)输出快递员走过的小区个数、派送快递的总个数、接收快递的总个数。
实验提示:
(1)每个结点应有两个数据域,分别用于存放收件数和派件数。
(2)可借助数组或手动输入来更新每个小区派送和接收快递的个数。
(3)可借助数组或列表来完成计数操作。
综合实验4 判断双链表是否对称
实验目的:深入理解双链表的存储结构,熟练掌握双链表的基本操作。
实验背景:我们在对双链表执行遍历操作时,既可从第一个元素开始访问,直到最后一个元素;也可从最后一个元素开始访问,直到第一个元素。若此时遍历所得的序列相同,我们则将其称为对称双链表(简称对称表,如图2-39所示),反之称为非对称双链表(简称非对称表)。请判断某一双链表是否为对称表。
图2-39 对称表
实验内容:创建文件ex030502_04.py,并在其中编写判断双链表是否对称的程序,对给定的双链表进行判断,具体如下。
(1)创建双链表A,并将值为“d”“e”“e”和“d”的结点依次存入双链表A中。
(2)创建双链表B,并将值为“墨”“磨”“人”“非”“人”“磨”和“墨”的结点依次存入双链表B中。
(3)利用双链表从两端向中间遍历,判断第一个结点的值与最后一个结点的值是否匹配,第二个结点的值是否与倒数第二个结点的值匹配,依次类推,直至判断结束。
(4)根据(3)中的比对结果,给出相应结论。
实验提示:
(1)使用两个指针访问双链表中的结点,其中一个指针从双链表中的第一个结点向最后一个结点移动,另一个指针从双链表的最后一个结点向第一个结点移动。
(2)表中结点的个数不同时,结束条件也不同,可按结点个数的奇偶来分别处理。
(3)字符串匹配时,可调用operator.eq()函数。
综合实验5 双十一快递派送
实验目的:深入理解循环双链表的存储结构,熟练掌握循环双链表的基本操作。
实验背景:“双十一”来临之际,瑶湖快递公司为应对即将到来的快递高峰,向各地增派了人手。快递员陈晓红被安排至N市高新技术开发区,配合原快递员张小明共同负责该区内10个居民小区的快递派送任务。两人会在每天上午9点和下午2点从公司总部同时出发,分别按顺时针和逆时针方向进行派送,图2-40所示为两人派送路线。快递公司规定,快递员陈晓红负责从第⑩小区到第①小区取件,快递员张小明负责从第①小区到第⑩小区派件。若某小区的派件数或取件数为零,快递员则可忽略这一小区,直接到下一个小区进行服务。每日派送结束后,公司会对每位快递员派送过的小区数及取件数或派件数进行清点,假设表2-20所示为两人今日工作记录,请借助于循环双链表来实现公司今日的清点任务。
图2-40 两位快递员配送路线
表2-20 两位快递员今日工作记录
实验内容:创建文件
ex030502_05.py,并在其中编写清点快递任务的程序,具体如下。
(1)创建循环双链表A,将小区编号作为参数创建相应结点,并依次链入A中。
(2)记录下每位快递员所经过的小区个数,再分别将收件数和寄件数记录至当前结点的数据域中。
(3)遍历链表,对每个结点内收件数和寄件数分别求和并输出。
实验提示:
(1)每个结点应有两个数据域。
(2)快递员陈晓红的前进方向应该与张小明的方向相反。