一、实验目的
1.掌握用Python定义线性表的循环链式存储类型;
2.掌握用Python调试循环链表的基本方法;
3.掌握循环链表的基本操作,插入、删除、查找、以及有序循环链表的合并等算法的实现;
二、实验环境
1.Windows操作系统的计算机
2.Python3.7环境平台和PyCharm编辑器
三、实验说明
1.实现线性表的循环链式存储结构的基本操作。
2.实验中如无特别说明,均要求使用脚本(.py)方式编写代码。
3.自主编写程序,必要时参考相关资料。
4.实验学时:2学时
四、实验内容和步骤
1.实验内容
(1) 基础实验题
设计整数循环单链表的基本运算程序,并用相关数据进行测试。
参考框架:
class LinkNode: #循环单链表结点类
def __init__(self,data=None): #构造函数
……
class CLinkList: #循环单链表类
def __init__(self): #构造函数
……
def CreateListF(self, a): #头插法:由数组a整体建立循环单链表
……
def CreateListR(self, a): #尾插法:由数组a整体建立循环单链表
……
def Add(self, e): #在线性表的末尾添加一个元素e
……
def getsize(self): #返回长度
……
def GetNo(self,e): #查找第一个为e的元素的序号
……
def Insert(self, i, e): #在线性表中序号i位置插入元素e
……
def Delete(self,i): #在线性表中删除序号i位置的元素
……
def display(self): #输出线性表
……
if __name__ == '__main__': #主程序(给下面每条语句做注释,解释实现功能)
L=CLinkList()
print()
print(" 建立循环单链表L")
a=[1,2,3,4,5,6]
print(" 1-6创建L")
L.CreateListR(a)
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()
print(" 插入6-11")
for i in range(6,11):
L.Add(i)
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()
print(" 序号为2的元素=%d" %(L[2]))
print(" 设置序号为2的元素为20")
L[2]=20
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()
x=6
print(" 第一个值为%d的元素序号=%d" %(x,L.GetNo(x)))
n=L.getsize()
for i in range(n-2):
print(" 删除首元素")
L.Delete(0)
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()
(2) 应用实验题
现有两个递增有序的整数单链表A和B,设计一个尽可能高效的算法,求两个集合的交集C,C仍然是递增有序的单链表,并给出算法的时间和空间复杂度。例如A=(1, 3, 5, 7),B=(1, 2, 4, 5, 7),交集C=(1, 5, 7)。
参考框架:
from LinkList import LinkList #导入上节课建好的Linklist类
from LinkList import LinkNode #导入上节课建好的LinkNode类
def Inter(A,B):
C=LinkList()
t=C.head #t指向C的尾结点
_
_
while p!=None and q!=None:
if p.data<q.data: #忽略较小结点
_
elif q.data<p.data: #忽略较小结点
_
else: #仅仅将公共结点添加到C中
_
_
_
_
return C
A=LinkList()
a=[1,3,5,7]
A.CreateListR(a)
_
B=LinkList()
_
_
print("B: ",end=''),B.display()
print("Inter")
C=Inter(A,B)
_
2.实验步骤
(1)分析实验内容,写出程序大致框架或完整的程序代码。
(2)进入Python集成环境。
(3)编辑程序并进行保存。
(4)运行程序,若有错误,修改错误后再次运行,如此反复进行到不显示出错为止。
(5)检查程序输出结果。
五、实验代码与结果(程序运行代码及其结果)
1. (1)给出算法的基本设计思想。
(2)根据设计思想,采用Python语言描述算法,关键之处给出注释。
class LinkNode: #循环单链表结点类
def __init__(self,data=None): #构造函数
self.data=data
self.next=None
class CLinkList: #循环单链表类
def __init__(self): #构造函数
self.head=LinkNode()
self.next=self.head
def CreateListF(self,a): #头插法:由数组a整体建立循环单链表
for i in range(self,a):
s=LinkNode(a[i])
s.next=self.head.next
self.head.next=self.head
def CreateListR(self,a): #尾插法:由数组a整体建立循环单链表
t=self.head
for i in range(0,len(a)):
s=LinkNode(a[i]);
t.next=s
t=s
t.next=self.head
def geti(self,i): #返回序号为i的结点
p=self.head
j=-1
while(j<i ):
j+=1
p=p.next
if p==self.head:
break
return p
def __getitem__(self,i): #求序号为i的元素
assert i>=0
p=self.geti(i)
assert p!=self.head
return p.data
def __setitem__(self,i,x): #设置序号为i的元素
assert i>=0
p=self.geti(i)
assert p!=self.head
p.data=x
def Add(self,e): #在线性表的末尾添加一个元素e
s=LinkNode(e)
p=self.head
while p.next!=self.head:
p=p.next
p.next=s
s.next=self.head
def getsize(self): #获取链表长度
p=self.head
cnt=0
while p.next!=self.head:
cnt+=1
p=p.next
return cnt
def GetNo(self,e): #查找第一个为e的元素的序号
j=0
p=self.head.next
while p!=self.head and p.data!=e:
j+=1
p=p.next
if p!=self.head:
return -1
else:
return j
def Insert(self,i,e): #在线性表中序号i位置插入元素e
assert i >=0
s=LinkNode(e)
if(i==0):
s=LinkNode(e)
else:
p=self.geti(i-1)
assert p!=self.head
s.next=p.next
p.next=s
def Delete(self,i): #在线性表中删除序号i位置的元素
assert i>=0
p=self.geti(i-1)
assert p.next!=self.head
p.next=p.next.next
def display(self): #输出线性表
p=self.head.next
while p!=self.head:
print(p.data,end=' ')
p=p.next
print()
if __name__ == '__main__':
L=CLinkList() #创建循环列表(空值)
print()
print(" 建立循环单链表L")#输出循环列表L
a=[1,2,3,4,5,6]
print(" 1-6创建L")
L.CreateListR(a)#创建循环列表————尾插法
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()#获取链表长度并输出其结果
print(" 插入6-11")
for i in range(6,11):
L.Add(i)#往链表添加元素‘6’至‘11’
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()#获取链表长度并输出其结果
print(" 序号为2的元素=%d" %(L[2]))
print(" 设置序号为2的元素为20")
L[2]=20#将序号2的元素更改为‘20’
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()#获取链表长度并输出其结果
x=6
print(" 第一个值为%d的元素序号=%d" %(x,L.GetNo(x))) #查找第一个为6的元素的序号
n=L.getsize()#获取链表长度并将其赋值给‘n’
for i in range(n-2):
print(" 删除首元素")
L.Delete(0)#删除链表序号0的元素(即第一个元素)
print(" L[长度=%d]: " %(L.getsize()),end=''),L.display()#获取链表长度并输出其结果
2. (1)给出算法的基本设计思想。
(2)根据设计思想,采用Python语言描述算法,关键之处给出注释。
import time
from LinkList import LinkList
from LinkList import LinkNode
def Inter(A,B):
C=LinkList()
t=C.head
p=A.head.next
q=B.head.next
while p!=None and q!=None:
if p.data<q.data:
p=p.next
elif q.data<p.data:
q=q.next
else:
t.next=p
t=p
p=p.next
q=q.next
return C
t1 = time.time()
A = LinkList()
a = [1,3,5,7]
A.CreateListR(a)
print("A:",end = " "),A.display()
B = LinkList()
b = [1,2,4,5,7]
B.CreateListR(b)
print("B:",end = " "),B.display()
print("Inter")
C=Inter(A,B)
print("C:",end = " "),C.display()
t2 = time.time()
print("运行时间:",t2 - t1)