一、循环链表
1、概念
循环链表:就是首尾相连的链表,通过任意一个节点,都能将整个链表遍历一遍
分类:单向循环链表、双向循环链表
2、单向循环链表的类格式
单向循环链表也就是单向链表的最后一个节点的next域不再为None,而是第一个节点
3、单向循环链表操作
①创建
#封装节点的类
class Node:
def __init__(self,data):
self.data = data
self.next = None
#封装单向循环链表类
class LinkList:
def __init__(self,node = None):
self.size = 0
self.head = node
②判空
#判空
def is_empty(self):
return self.size == 0
③尾插
#尾插
def add_tail(self,data):
#创建一个新的节点
node = Node(data)
#判空
if self.is_empty():
self.head = node
node.next = node
else:
#找到最后一个节点
q = self.head
while q.next != self.head:
q = q.next
q.next = node
node.next = self.head
#链表长度自增
self.size += 1
④遍历
#遍历
def show(self):
#判空
if self.is_empty():
print("失败")
else:
#两种: 长度遍历 位置遍历(循环结束 多打印一次)
q = self.head
while q.next != self.head:
print("%d"%(q.data),end=" ")
q = q.next
print("%d"%(q.data),end=" ")
print()
⑤尾删
#尾删
def del_tail(self):
#判空
if self.is_empty():
print("删除失败,列表为空!")
else:
#判断长度是否为1 是否只有一个节点
if self.size == 1:
deleted_value = self.head.next.data
self.head = None
else:
q = self.head
i=1
while i<self.size-1:
q = q.next
i+=1
deleted_value = q.next.data
q.next = self.head
#删除成功 链表长度自减
self.size -=1
print(f"删除成功,值{deleted_value}已被删除!")
⑥完整代码
#判断输入是否为整数
def get_int(prompt):
while True:
try:
value = int(input(prompt))
return value
except ValueError:
print("无效输入,请输入一个整数。")
#判断输入是否在合理的范围内
def get_choice(prompt, min_val, max_val):
while True:
try:
value = int(input(prompt))
if min_val <= value <= max_val:
return value
else:
print("无法处理您的指令,请重新输入。")
except ValueError:
print("无效输入,请输入一个整数。")
#封装节点的类
class Node:
def __init__(self,data):
self.data = data
self.next = None
#封装单向循环链表类
class LinkList:
def __init__(self,node = None):
self.size = 0
self.head = node
#判空
def is_empty(self):
return self.size == 0
#尾插
def add_tail(self,data):
#创建一个新的节点
node = Node(data)
#判空
if self.is_empty():
self.head = node
node.next = node
else:
#找到最后一个节点
q = self.head
while q.next != self.head:
q = q.next
q.next = node
node.next = self.head
#链表长度自增
self.size += 1
#遍历
def show(self):
#判空
if self.is_empty():
print("失败")
else:
#两种: 长度遍历 位置遍历(循环结束 多打印一次)
q = self.head
while q.next != self.head:
print("%d"%(q.data),end=" ")
q = q.next
print("%d"%(q.data),end=" ")
print()
#尾删
def del_tail(self):
#判空
if self.is_empty():
print("删除失败,列表为空!")
else:
#判断长度是否为1 是否只有一个节点
if self.size == 1:
deleted_value = self.head.next.data
self.head = None
else:
q = self.head
i=1
while i<self.size-1:
q = q.next
i+=1
deleted_value = q.next.data
q.next = self.head
#删除成功 链表长度自减
self.size -=1
print(f"删除成功,值{deleted_value}已被删除!")
linkList = LinkList()
linkList.add_tail(1)
linkList.add_tail(2)
linkList.add_tail(3)
linkList.add_tail(4)
linkList.add_tail(5)
# 菜单
while True:
print("\n菜单:")
print("1. 显示所有数据")
print("2. 添加数据")
print("3. 删除数据")
print("4. 退出")
choice = get_choice("请选择操作:", 1, 4)
if choice == 1: # 显示所有数据
linkList.show()
elif choice == 2: # 添加数据
value = get_int("请输入一个整数:")
linkList.add_tail(value)
print(f"数字{value}加入成功。")
elif choice == 3: # 删除数据
a = input("删除后无法恢复,你确定吗?: ")
if a.lower() in ["y", "yes", "Y", "Yes", "YES", "确定", "我确定", ""]:
linkList.del_tail()
else:
print("删除操作已取消。")
elif choice == 4: # 退出程序
print("程序已退出。")
break
4、双向循环链表操作
①创建
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prior = None # 新增前驱指针
#封装双向循环链表类
class DoubleCircularLinkList:
def __init__(self, node=None):
self.size = 0
self.head = node
②判空
#判空
def is_empty(self):
return self.size == 0
③尾插
#尾插
def add_tail(self, data):
#创建一个新的节点
node = Node(data)
#判空
if self.is_empty():
# 初始化双向循环链表
self.head = node
node.next = node
node.prior = node
else:
tail = self.head.prior # 获取尾节点
tail.next = node
node.prior = tail
node.next = self.head
self.head.prior = node
#链表长度自增
self.size += 1
④遍历
#遍历
def show(self):
#判空
if self.is_empty():
print("链表为空,显示失败!")
else:
#两种: 长度遍历 位置遍历(循环结束 多打印一次)
q = self.head
for _ in range(self.size):
print(f"{q.data}", end=" ")
q = q.next
print()
⑤尾删
#尾删
def del_tail(self):
#判空
if self.is_empty():
print("删除失败,列表为空!")
else:
tail = self.head.prior
#判断长度是否为1 是否只有一个节点
if self.size == 1:
deleted_value = tail.data
self.head = None
else:
deleted_value = tail.data
new_tail = tail.prior
new_tail.next = self.head
self.head.prior = new_tail
#删除成功 链表长度自减
self.size -= 1
print(f"删除成功,值{deleted_value}已被删除!")
⑥完整代码
#判断输入是否为整数
def get_int(prompt):
while True:
try:
value = int(input(prompt))
return value
except ValueError:
print("无效输入,请输入一个整数。")
#判断输入是否在合理的范围内
def get_choice(prompt, min_val, max_val):
while True:
try:
value = int(input(prompt))
if min_val <= value <= max_val:
return value
else:
print("无法处理您的指令,请重新输入。")
except ValueError:
print("无效输入,请输入一个整数。")
#封装节点的类
class Node:
def __init__(self, data):
self.data = data
self.next = None
self.prior = None # 新增前驱指针
#封装双向循环链表类
class DoubleCircularLinkList:
def __init__(self, node=None):
self.size = 0
self.head = node
#判空
def is_empty(self):
return self.size == 0
#尾插
def add_tail(self, data):
#创建一个新的节点
node = Node(data)
#判空
if self.is_empty():
# 初始化双向循环链表
self.head = node
node.next = node
node.prior = node
else:
tail = self.head.prior # 获取尾节点
tail.next = node
node.prior = tail
node.next = self.head
self.head.prior = node
#链表长度自增
self.size += 1
#遍历
def show(self):
#判空
if self.is_empty():
print("链表为空,显示失败!")
else:
#两种: 长度遍历 位置遍历(循环结束 多打印一次)
q = self.head
for _ in range(self.size):
print(f"{q.data}", end=" ")
q = q.next
print()
#尾删
def del_tail(self):
#判空
if self.is_empty():
print("删除失败,列表为空!")
else:
tail = self.head.prior
#判断长度是否为1 是否只有一个节点
if self.size == 1:
deleted_value = tail.data
self.head = None
else:
deleted_value = tail.data
new_tail = tail.prior
new_tail.next = self.head
self.head.prior = new_tail
#删除成功 链表长度自减
self.size -= 1
print(f"删除成功,值{deleted_value}已被删除!")
linkList = DoubleCircularLinkList()
linkList.add_tail(1)
linkList.add_tail(2)
linkList.add_tail(3)
linkList.add_tail(4)
linkList.add_tail(5)
while True:
print("\n菜单:")
print("1. 显示所有数据")
print("2. 添加数据")
print("3. 删除数据")
print("4. 退出")
choice = get_choice("请选择操作:", 1, 4)
if choice == 1: # 显示所有数据
linkList.show()
elif choice == 2: # 添加数据
value = get_int("请输入一个整数:")
linkList.add_tail(value)
print(f"数字{value}加入成功。")
elif choice == 3: # 删除数据
a = input("删除后无法恢复,你确定吗?: ")
if a.lower() in ["y", "yes", "Y", "Yes", "YES", "确定", "我确定", ""]:
linkList.del_tail()
else:
print("删除操作已取消。")
elif choice == 4: # 退出程序
print("程序已退出。")
break
二、栈
1、概念
栈的概念:操作受限的线性表,对数据的插入和删除操作只能在同一端操作
栈的特点:先进后出(FILO ---->First In Last Out) 、后进先出(LIFO ---->Last In First Out)
栈顶:能够被操作的一端称为栈顶
栈底:不能被操作的一端,称为栈底
种类:顺序栈、链式栈
基本操作:创建栈、判空、入栈、出栈、获取栈顶元素、求栈的大小、遍历栈
2、顺序栈
①概念
顺序存储的栈 叫顺序栈
②顺序栈的组成
需要使用一个容器存储一个栈,例如列表
③栈的实例
# 判断选择是否合理
def get_choice(prompt, min_val, max_val):
while True:
try:
value = int(input(prompt))
if min_val <= value <= max_val:
return value
else:
print(f"输入不在范围{min_val}-{max_val}之间,请重新输入。")
except ValueError:
print("无效输入,请输入一个整数。")
# 定义链式栈的节点
class Node:
def __init__(self, data):
self.data = data
self.next = None
# 定义链式栈
class Stack:
def __init__(self):
self.top = None # 栈顶节点
self.size = 0 # 栈的大小
# 判断栈是否为空
def is_empty(self):
return self.top is None
# 入栈操作
def push(self, value):
new_node = Node(value)
new_node.next = self.top
self.top = new_node
self.size += 1
# 弹出栈顶元素
def pop(self):
if self.is_empty():
print("栈为空,无法弹出元素!")
else:
popped_value = self.top.data
self.top = self.top.next
self.size -= 1
print(f"弹出元素:{popped_value}")
# 返回栈顶元素
def peek(self):
if self.is_empty():
print("栈为空,无栈顶元素!")
return None
return self.top.data
# 遍历栈
def show(self):
if self.is_empty():
print("栈为空,无法遍历!")
else:
current = self.top
print("当前栈元素:", end=" ")
while current:
print(current.data, end=" ")
current = current.next
print()
# 返回栈的大小
def get_size(self):
return self.size
# 创建栈对象
stack = Stack()
stack.push("hello")
stack.push("world")
stack.push("hello")
stack.push("meimei")
# 菜单
while True:
print("\n菜单:")
print("1. 显示所有数据")
print("2. 显示栈的大小")
print("3. 添加数据")
print("4. 删除数据")
print("5. 返回栈顶元素")
print("6. 退出")
choice = get_choice("请选择操作:", 1, 6)
if choice == 1: # 显示所有数据
stack.show()
elif choice == 2: # 显示栈的大小
print(f"栈的大小:{stack.get_size()}")
elif choice == 3: # 添加数据
value = input("请在这里输入你想入栈的数据:")
stack.push(value)
print(f"数据“{value}”已添加到栈。")
elif choice == 4: # 删除数据
stack.pop()
elif choice == 5: # 返回栈顶元素
top_value = stack.peek()
if top_value is not None:
print(f"栈顶元素:{top_value}")
elif choice == 6: # 退出程序
print("程序已退出。")
break