引言
单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。
目录
结点信息类的构造
class student: #结点信息类
def __init__(self, no, name, Math,Eng): # 构造函数,初始化变量
self.no = no # 学号
self.name = name # 姓名
self.suxue = Math # 数学成绩
self.yingyu = Eng # 英语成绩
self.next = None #创建指针
def __repr__(self): # 输出结点的格式
return str(self.no) + "\t\t" + str(self.name) + "\t\t" + str(self.suxue) + "\t\t" + str(self.yingyu) #将信息类型转化为字符串
链表类的构造
class ListXS: #生成链表类
def __init__(self): #初始化单链表
self.headnode = student(None,None,None,None) #创建头结点
self.headnode.next = None #头结点指针
链表类方法的构造
判断链表是否为空
def is_empty(self): #判断链表是否为空
return self.headnode.next is None #判断链表长度是否等于0
在链表尾部插入新结点
def append(self,no, name, Math,Eng): #在链表尾部插入新结点
this_node = student(no, name, Math,Eng) #创建新结点
p = self.headnode #获取链表位置
while p.next: #循环获取第i位前一个的结点
p = p.next #更新p的值
this_node.next = p.next #新结点指针指向None
p.next = this_node #将原链表指针指向新结点
在链表表头插入新结点
def front_add(self,no, name, Math,Eng): #在链表表头插入新结点
this_node = student(no, name, Math,Eng) #创建新结点
p = self.headnode #获取链表位置
this_node.next = self.headnode.next #将链表的首元结点设置为新结点
self.headnode.next = this_node #新链表首元结点的指针域指向原链表的首元结点
在第index处插入新结点
def insert(self,no, name, Math,Eng, index): #在第index处插入新结点
this_node = student(no, name, Math,Eng) #创建新结点
p = self.headnode #获取原链表首元结点
while index: #循环获取第i位前一个的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
this_node.next = p.next #新结点指针指向原链表第i位置的结点
p.next = this_node #原链表第i-1位置的结点的指针指向新结点
删除当前链表中对象的首元结点
def pop_front(self): #删除当前链表中对象的首元结点
if self.headnode.next == None: #判断链表是否为空
print("Error") #如果链表为空,则操作失败
print('请输入正确的操作:') #重新输入操作
else: #如果链表含有一个或一个以上的结点,则执行以下操作
p = self.headnode.next.next #获取原链表首元结点的下一个结点信息
self.headnode.next = p #将原链表首元结点下一个结点作为首元结点
删除当前链表中对象的尾结点
def pop_back_bad(self): #删除当前链表中对象的尾结点
if self.headnode.next == None: #判断链表是否为空
print("Error") #如果链表为空,则操作失败
print('请输入正确的操作:') #重新输入操作
elif self.headnode.next.next == None: #判断链表中是否只包含一个结点
self.headnode.next = None #将头结点的指针指向None
else: #判断链表是否含有一个以上的结点
p = self.headnode #获取链表位置
while p.next.next != None: #循环获取尾结点前一个的结点
p = p.next #更新p的值
p.next = None #将尾结点前一个的结点的指针指向None
删除第index个结点
def delete(self, index): #删除第index个结点
if self.headnode.next == None: #判断链表是否为空
print("Error") #如果链表为空,则操作失败
print('请输入正确的操作:') #重新输入操作
elif index == 0: #判断删除位置index是否在链表表头
self.headnode.next = self.headnode.next.next #将头结点的指针指向原链表首元结点的下一个结点
else: #删除位置不在链表表头
p = self.headnode #获取链表位置
while index: #循环获取第i位前一个的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
p.next = p.next.next #将第i-1位置的结点的指针指向i位置的下一个结点
更新第index结点的值
def update(self, data, index): #更新第index结点的值
if index == 0: #判断更新位置index是否在链表表头
data.next = self.headnode.next.next #将
self.headnode.next = data #如果链表只有一个结点,则将该结点的数据域改为data
else: #如果链表存在一个结点以上,则执行以下操作
p = self.headnode #获取原链表首元结点
while index: #循环获取第i位的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
data.next = p.next.next
p.next = data
获取第index节点的值
def get_data(self, index): #获取第index节点的值
if index == 0: #判断获取位置index是否在链表表头
print(self.headnode.next) #如果链表只有一个结点,则返回该结点的数据域
else: #如果链表存在一个结点以上,则执行以下操作
p = self.headnode #获取原链表首元结点
while index: #循环获取第i位的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
print(p.next) #输出获取的结点
获取元素i在结点对象的引用
def search(self,i): #获取元素i在结点对象的引用
p = self.headnode #获取原链表首元结点
while p.next and str(p.next) != str(i): #循环找到结点数据域等于i的结点
p = p.next #更新p的值
print(p.next) #输出获取的结点
return p.next #返回结点引用
清空链表
def clear(self): #清空链表
self.headnode.next = None #链表头指针指向None
print('True') #清空链表成功
打印链表
def PrintList(self): #打印链表
if self.headnode.next == None: #判断链表是否为空表
return None #如果链表为空,则返回None
else: #如果链表不为空,则执行以下操作
p = self.headnode #获取原链表首元结点
while p.next: #将链表循环一次
p = p.next #更新p的值
print(p) #输出每个结点的数据域
return p #返回每个结点的数据域
读取txt文件数据,并存入数组
def ReadFromFile(self,txt_path): #读取txt文件数据,并存入数组
with open(r"{0}".format(txt_path), "r",encoding='utf-8') as f: #读取txt文件里的数据
next(f) # 跳过第一行内容读入
row = f.readlines() #读取每一行的数据
a = []
for i in range(len(row)):
num_row = row[i].strip().split(",") # strip():移除字符串头尾指定的字符(默认为空格或换行符)或字符序列,split():指定分隔符对字符串进行切片
a.append(num_row)
return a #返回整个数组
将链表的数据写入txt文件中
def Writer_data(self,address): #将链表的数据写入txt文件中
with open(r"{0}".format(address), "w", encoding='utf-8') as f: #储存路径
f.write('学号 姓名 数学成绩 英语成绩'+'\n')
p = self.headnode.next # 获取原链表首元结点
while p.next: #将链表循环一次
f.write(str(p)+'\n') #将链表中的数据写入txt文件中
p = p.next #更新循环条件
print('True') #写入成功
完整代码
class student: #结点信息类
def __init__(self, no, name, Math,Eng): # 构造函数,初始化变量
self.no = no # 学号
self.name = name # 姓名
self.suxue = Math # 数学成绩
self.yingyu = Eng # 英语成绩
self.next = None #创建指针
def __repr__(self): # 输出结点的格式
return str(self.no) + "\t\t" + str(self.name) + "\t\t" + str(self.suxue) + "\t\t" + str(self.yingyu) #将信息类型转化为字符串
class ListXS: #生成链表类
def __init__(self): #初始化单链表
self.headnode = student(None,None,None,None) #创建头结点
self.headnode.next = None #头结点指针
def is_empty(self): #判断链表是否为空
return self.headnode.next is None #判断链表长度是否等于0
def append(self,no, name, Math,Eng): #在链表尾部插入新结点
this_node = student(no, name, Math,Eng) #创建新结点
p = self.headnode #获取链表位置
while p.next: #循环获取第i位前一个的结点
p = p.next #更新p的值
this_node.next = p.next #新结点指针指向None
p.next = this_node #将原链表指针指向新结点
def front_add(self,no, name, Math,Eng): #在链表表头插入新结点
this_node = student(no, name, Math,Eng) #创建新结点
p = self.headnode #获取链表位置
this_node.next = self.headnode.next #将链表的首元结点设置为新结点
self.headnode.next = this_node #新链表首元结点的指针域指向原链表的首元结点
def insert(self,no, name, Math,Eng, index): #在第index处插入新结点
this_node = student(no, name, Math,Eng) #创建新结点
p = self.headnode #获取原链表首元结点
while index: #循环获取第i位前一个的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
this_node.next = p.next #新结点指针指向原链表第i位置的结点
p.next = this_node #原链表第i-1位置的结点的指针指向新结点
def pop_front(self): #删除当前链表中对象的首元结点
if self.headnode.next == None: #判断链表是否为空
print("Error") #如果链表为空,则操作失败
print('请输入正确的操作:') #重新输入操作
else: #如果链表含有一个或一个以上的结点,则执行以下操作
p = self.headnode.next.next #获取原链表首元结点的下一个结点信息
self.headnode.next = p #将原链表首元结点下一个结点作为首元结点
def pop_back_bad(self): #删除当前链表中对象的尾结点
if self.headnode.next == None: #判断链表是否为空
print("Error") #如果链表为空,则操作失败
print('请输入正确的操作:') #重新输入操作
elif self.headnode.next.next == None: #判断链表中是否只包含一个结点
self.headnode.next = None #将头结点的指针指向None
else: #判断链表是否含有一个以上的结点
p = self.headnode #获取链表位置
while p.next.next != None: #循环获取尾结点前一个的结点
p = p.next #更新p的值
p.next = None #将尾结点前一个的结点的指针指向None
def delete(self, index): #删除第index个结点
if self.headnode.next == None: #判断链表是否为空
print("Error") #如果链表为空,则操作失败
print('请输入正确的操作:') #重新输入操作
elif index == 0: #判断删除位置index是否在链表表头
self.headnode.next = self.headnode.next.next #将头结点的指针指向原链表首元结点的下一个结点
else: #删除位置不在链表表头
p = self.headnode #获取链表位置
while index: #循环获取第i位前一个的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
p.next = p.next.next #将第i-1位置的结点的指针指向i位置的下一个结点
def update(self, data, index): #更新第index结点的值
if index == 0: #判断更新位置index是否在链表表头
data.next = self.headnode.next.next #将
self.headnode.next = data #如果链表只有一个结点,则将该结点的数据域改为data
else: #如果链表存在一个结点以上,则执行以下操作
p = self.headnode #获取原链表首元结点
while index: #循环获取第i位的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
data.next = p.next.next
p.next = data
def get_data(self, index): #获取第index节点的值
if index == 0: #判断获取位置index是否在链表表头
print(self.headnode.next) #如果链表只有一个结点,则返回该结点的数据域
else: #如果链表存在一个结点以上,则执行以下操作
p = self.headnode #获取原链表首元结点
while index: #循环获取第i位的结点
p = p.next #更新p的值
index -= 1 #更新循环的条件
print(p.next) #输出获取的结点
def search(self,i): #获取元素i在结点对象的引用
p = self.headnode #获取原链表首元结点
while p.next and str(p.next) != str(i): #循环找到结点数据域等于i的结点
p = p.next #更新p的值
print(p.next) #输出获取的结点
return p.next #返回结点引用
def clear(self): #清空链表
self.headnode.next = None #链表头指针指向None
print('True') #清空链表成功
#
def PrintList(self): #打印链表
if self.headnode.next == None: #判断链表是否为空表
return None #如果链表为空,则返回None
else: #如果链表不为空,则执行以下操作
p = self.headnode #获取原链表首元结点
while p.next: #将链表循环一次
p = p.next #更新p的值
print(p) #输出每个结点的数据域
return p #返回每个结点的数据域
def ReadFromFile(self,txt_path): #读取txt文件数据,并存入数组
with open(r"{0}".format(txt_path), "r",encoding='utf-8') as f: #读取txt文件里的数据
next(f) # 跳过第一行内容读入
row = f.readlines() #读取每一行的数据
a = []
for i in range(len(row)):
num_row = row[i].strip().split(",") # strip():移除字符串头尾指定的字符(默认为空格或换行符)或字符序列,split():指定分隔符对字符串进行切片
a.append(num_row)
return a #返回整个数组
def Writer_data(self,address): #将链表的数据写入txt文件中
with open(r"{0}".format(address), "w", encoding='utf-8') as f: #储存路径
f.write('学号 姓名 数学成绩 英语成绩'+'\n')
p = self.headnode.next # 获取原链表首元结点
while p.next: #将链表循环一次
f.write(str(p)+'\n') #将链表中的数据写入txt文件中
p = p.next #更新循环条件
print('True') #写入成功
def main(): #测试和调试
a =True
data = ListXS()
while a:
a = input('请选择你想要实现链表的功能:'+'\n'+'1.在链表尾部插入新结点'+'\n'+'2.在链表表头插入新结点'+'\n'+'3.在指定位置index处插入新结点'+'\n'+'4.删除当前链表中对象的首元结点'+'\n'+'5.删除当前链表中对象的尾结点'+'\n'+'6.删除指定index位置的结点'+'\n'+'7.更新第index结点的值'+'\n'+'8.获取第index结点的值'+'\n'+'9.获取元素i在结点对象的引用'+'\n'+'10.判断链表是否为空'+'\n'+'11.清空链表'+'\n'+'12.打印链表'+'\n'+'13.读取txt文件数据,并存入链表'+'\n'+'14.将链表的数据写入txt文件中'+'\n'+'15.结束操作'+'\n'+'请输入你的操作:')
if a == '1':
print("------------------在链表尾部插入新结点-----------------------------")
z,x,c,v = input('请输入插入新结点信息并用,分隔:').split(',')
data.append(z,x,c,v)
data.PrintList()
elif a == '2':
print("------------------在链表头部插入新结点-----------------------------")
z,x,c,v = input('请输入插入新结点信息并用,分隔:').split(',')
data.front_add(z,x,c,v)
data.PrintList()
elif a == '3':
print("---------------------向指定位置插入新结点结点-----------------------------")
z, x, c, v = input('请输入插入新结点信息并用,分隔:').split(',')
b = int(input('请输入插入位置:'))
data.insert(z,x,c,v,b)
data.PrintList()
elif a == '4':
print("------------------删除首元结点-----------------------------")
data.pop_front()
data.PrintList()
elif a == '5':
print("------------------删除尾结点-----------------------------")
data.pop_back_bad()
data.PrintList()
elif a == '6':
print("---------------------删除指定位置的结点-----------------------------")
z = int(input("请输入删除结点的位置:"))
data.delete(z)
data.PrintList()
elif a == '7':
print("--------------------------更新第index结点的值----------------------------------")
z, x, c, v = input('请输入新结点信息并用,分隔:').split(',')
b = int(input('请输入更新位置:'))
data.update(student(z,x,c,v),b)
data.PrintList()
elif a == '8':
print("---------------------获取第index位置的结点值-----------------------------")
z = int(input('请输入获取位置:'))
data.get_data(z)
elif a == '9':
print("---------------------获取第index结点对象的引用-----------------------------")
z, x, c, v = input('请输入查找信息:').split(',')
data.search(student(z,x,c,v))
elif a == '10':
print("--------------------------判断链表是否为空----------------------------------")
print(data.is_empty())
elif a == '11':
print("--------------------------将链表中清空----------------------------------")
data.clear()
elif a == '12':
print("--------------------------打印链表----------------------------------")
data.PrintList()
elif a == '13':
print("------------------读取txt文件数据,将数据加入到链表中-----------------------------")
z = input("请输入txt文件名:")
for i in data.ReadFromFile(z):
data.append(i[0], i[1], i[2], i[3])
data.PrintList()
elif a == '14':
print("--------------------------将链表中的数据保存到txt文件中----------------------------------")
z = input('请输入保存txt文件名')
data.Writer_data(z)
elif a == '15':
print('--------------------------结束链表操作------------------------------')
a = False
else:
print('输入错误,请重新输入:')
continue
if __name__ == '__main__': #如果name等于main则运行
main() #运行main