一、双向链表
1.1 作用
双向链表也叫双面链表。
对于单向链表而言。只能通过头节点或者第一个节点出发,单向的访问后继节点,每个节点只能记录其后继节点的信息(位置),不能向前遍历。
所以引入双向链表,双向链表可以保持单向链表特点的基础上,让每个节点,既能向后访问后继节点,也可以向前访问前驱节点。
1.2 节点和链表类的定义
#定义节点类的类型
class Node:
#显性定义出构造函数
def __init__(self,data):
self.data = data #普通节点的数据域
self.next = None #保存下一个节点的链接域
self.prior = None #保存前一个节点饿链接域
#定义双向链表的类的类型
class DoubleLink:
#定义构造函数
def __init__(self,node = None):
self.head = node #头结点的head初始化为None
self.size = 0 #链表的初始长度为0
1.3 双向链表的相关操作(功能函数的封装)
1】判空
函数功能:判断双向链表是否为空。思路:判断头结点的数据域是否为0,或者判断头结点的链接域是否为None
函数返回值:空则返True 非空返回False
函数名:符合命名规则
参数列表:双向链表
#判空
def is_empty(self):
return self.head == None
# return self.size == 0
2】头插
函数功能:往双向链表中增加一个节点,并且是头插的方式。思路:如上图
函数返回值:可以是无,也可以bool类型
函数名:符合命名规则
参数列表:双向链表、要插入的元素
注意事项:判断双向链表是否为空。
插入成功,链表长度自增。
#头插
def add_head(self,data):
#创建出一个新的节点
node = Node(data)
#判断链表是否为空 分为空和非空情况
if self.is_empty():
self.head = node
else:
node.next = self.head
self.head.prior = node #node.next.prior = node
self.head = node
#插入成功 链表长度自增
self.size += 1
3】遍历
函数功能:依次打印出链表节点中的数据。(同思路)
函数返回值:无
函数名:符合命名规则
参数列表:双向链表
注意事项:判断双向链表是否为空
#遍历
def show(self):
#判空
if self.is_empty():
print("链表为空 遍历失败")
else:
q = self.head
while q:
print("%d "%(q.data),end = " ")
q = q.next
print()
4】任意位置插入
函数功能:在双向链表的任意位置插入数据
函数返回值:可以是无 也可以是bool
函数名:符合命名规则
参数列表:双向链表self、要插入的位置、要插入的数据
注意事项:
1、是否是第一个位置、最后一个位置、其他位置
#任意位置插入
def add_index(self,idex,data):
#判断插入的位置是否合理
if idex<1 or idex>self.size+1:
print("插入失败")
else:
#判断插入的位置是否是第一个位置
if idex == 1:
self.add_head(data)
else:
#创建新的节点
node = Node(data)
#找到要插入位置的前一个节点
q = self.head
i=1
while i<idex-1:
q = q.next
i+=1
# 判断插入的位置是否是最后一个节点
if q.next == None: # 如果为真 则插入的是最后一个位置
q.next = node
node.prior = q
else: # 说明插入不是最后一个
node.next = q.next
node.prior = q
q.next.prior = node
q.next = node
#插入成功 链表长度自增
self.size += 1
5】任意位置删除
函数功能:删除双向链表指定的位置
函数返回值:可以是无 可以是bool
函数名:符合命名规范
参数列表:双向链表self、删除的位置
注意事项:
1.判空
2.判断删除的位置是否是第一个、最后一个、其他位置
#任意位置删除
def del_idex(self,idex):
#判空 判断位置是否合理:
if self.is_empty() or idex<1 or idex>self.size:
print("删除失败")
else:
#判断删除的是否是第一个节点
if idex == 1:
self.head = self.head.next
self.head.prior = None
else:
#判断删除的是否是最后一节节点
q = self.head
i = 1
while i<idex:
q = q.next
i+=1
if q.next:
#删除的不是最后一个节点
q.prior.next = q.next
q.next.prior = q.prior
else:
#删除的是最后一个
q.prior.next = None
#删除成功 链表长度自减
self.size -= 1
6】查找节点是否存在
函数功能:按值查找,返回真假(存在或者不存在)
函数返回值:bool
函数名:符合命名规则
参数列表:要查找的数据
#查找节点是否存在 按值
def find_node(self,data):
#判空
if self.is_empty():
print("查询失败")
else:
p = self.head
while p:
if p.data == data:
return True
p=p.next
return False
全部代码:
#定义节点类的类型
class Node:
#显性定义出构造函数
def __init__(self,data):
self.data = data #普通节点的数据域
self.next = None #保存下一个节点的链接域
self.prior = None #保存前一个节点饿链接域
#定义双向链表的类的类型
class DoubleLink:
#定义构造函数
def __init__(self,node = None):
self.head = node #头结点的head初始化为None
self.size = 0 #链表的初始长度为0
#判空
def is_empty(self):
return self.head == None
# return self.size == 0
#头插
def add_head(self,data):
#创建出一个新的节点
node = Node(data)
#判断链表是否为空 分为空和非空情况
if self.is_empty():
self.head = node
else:
node.next = self.head
self.head.prior = node #node.next.prior = node
self.head = node
#插入成功 链表长度自增
self.size += 1
#遍历
def show(self):
#判空
if self.is_empty():
print("链表为空 遍历失败")
else:
q = self.head
while q:
print("%d "%(q.data),end = " ")
q = q.next
print()
#任意位置插入
def add_index(self,idex,data):
#判断插入的位置是否合理
if idex<1 or idex>self.size+1:
print("插入失败")
else:
#判断插入的位置是否是第一个位置
if idex == 1:
self.add_head(data)
else:
#创建新的节点
node = Node(data)
#找到要插入位置的前一个节点
q = self.head
i=1
while i<idex-1:
q = q.next
i+=1
# 判断插入的位置是否是最后一个节点
if q.next == None: # 如果为真 则插入的是最后一个位置
q.next = node
node.prior = q
else: # 说明插入不是最后一个
node.next = q.next
node.prior = q
q.next.prior = node
q.next = node
#插入成功 链表长度自增
self.size += 1
#任意位置删除
def del_idex(self,idex):
#判空 判断位置是否合理:
if self.is_empty() or idex<1 or idex>self.size:
print("删除失败")
else:
#判断删除的是否是第一个节点
if idex == 1:
self.head = self.head.next
self.head.prior = None
else:
#判断删除的是否是最后一节节点
q = self.head
i = 1
while i<idex:
q = q.next
i+=1
if q.next:
#删除的不是最后一个节点
q.prior.next = q.next
q.next.prior = q.prior
else:
#删除的是最后一个
q.prior.next = None
#删除成功 链表长度自减
self.size -= 1
#查找节点是否存在 按值
def find_node(self,data):
#判空
if self.is_empty():
print("查询失败")
else:
p = self.head
while p:
if p.data == data:
return True
p=p.next
return False
#测试
if __name__ == "__main__":
#创建一个双向链表
doubleLink = DoubleLink()
#头插
doubleLink.add_head(10)
doubleLink.add_head(20)
doubleLink.add_head(30)
doubleLink.add_head(40)
doubleLink.add_head(50)
#遍历
doubleLink.show()
#任意位置插入
doubleLink.add_index(1,33)
doubleLink.show()
doubleLink.add_index(3, 999)
doubleLink.show()
doubleLink.add_index(8, 1111)
doubleLink.show()
#任意位置删除
doubleLink.del_idex(1)
doubleLink.show()
doubleLink.del_idex(4)
doubleLink.show()
doubleLink.del_idex(6)
doubleLink.show()
if(doubleLink.find_node(40)):
print("存在")
二、循环链表
2.1 概念
循环链表:就是首尾相连的链表,通过任意一个节点,都能将整个链表遍历一遍
分类:单向循环链表、双向循环链表
2.2 单向循环链表的类格式
单向循环链表也就是单向链表的最后一个节点的next域不再为None,而是第一个节点
2.3 操作
1】创建
#封装节点的类
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
2】判空
#判空
def is_empty(self):
return self.size == 0
#return self.head == None
3】尾插
#尾插
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
4】遍历
#遍历
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()
5】尾删
#尾删
def del_tail(self):
#判空
if self.is_empty():
print("删除失败")
else:
#判断长度是否为1 是否只有一个节点
if self.size == 1:
self.head = None
else:
q = self.head
i=1
while i<self.size-1:
q = q.next
i+=1
q.next = self.head
#删除成功 链表长度自减
self.size -=1
全部代码
#封装节点的类
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
#return self.head == None
#尾插
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:
self.head = None
else:
q = self.head
i=1
while i<self.size-1:
q = q.next
i+=1
q.next = self.head
#删除成功 链表长度自减
self.size -=1
#测试
if __name__ == "__main__":
#创建一个单向循环链表
linkList = LinkList()
#尾插
linkList.add_tail(1)
linkList.add_tail(2)
linkList.add_tail(3)
linkList.add_tail(4)
linkList.add_tail(5)
#显示
linkList.show()
#尾删
linkList.del_tail()
linkList.show()
linkList.del_tail()
linkList.show()
linkList.del_tail()
linkList.show()
linkList.del_tail()
linkList.show()
linkList.del_tail()
linkList.show()
三、栈
3.1 概念
栈的概念:操作受限的线性表,对数据的插入和删除操作只能在同一端操作
栈的特点:先进后出(FILO ---->First In Last Out) 、后进先出(LIFO ---->Last In First Out)
栈顶:能够被操作的一端称为栈顶
栈底:不能被操作的一端,称为栈底
种类:顺序栈、链式栈
基本操作:创建栈、判空、入栈、出栈、获取栈顶元素、求栈的大小、遍历栈
3.2 顺序栈
3.2.1 概念
顺序存储的栈 叫顺序栈
3.2.2 顺序栈的组成
1】需要使用一个容器存储一个栈,例如列表
3.3 栈的操作
- 创建一个空栈
- 添加数据
- 遍历栈
- 弹出栈顶元素(删除)
- 返回栈顶元素
- 判空
- 栈的大小
#封装一个栈的类
class Stack:
def __init__(self):
self.data = [] #使用列表来完成顺序栈
#判空
def is_empty(self):
return self.data == []
#增加数据
def push(self,value):
self.data.insert(0,value)
#遍历
def show(self):
for i in self.data:
print(i, end=" ")
print()
#弹出元素 删除
def pop(self):
#self.data.remove(self.data[0])
#self.data.pop(0)
del self.data[0]
#获取栈顶元素
def first_value(self):
return self.data[0]
#返回栈的大小
def size(self):
return len(self.data)
#测试
if __name__ == "__main__":
#创建一个栈
stack = Stack()
#增加元素
stack.push("hello")
stack.push("world")
stack.push("hello")
stack.push("meimei")
#遍历
stack.show()
#删除
stack.pop()
# 遍历
stack.show()
num = stack.first_value()
print(num)
size = stack.size()
print(size)
标签:node,head,Python,self,day3,链表,数据结构,data,def
From: https://blog.csdn.net/m0_67609958/article/details/144035104