🎬 博客主页:楼下安同学的博客
🎥 本文由 楼下安同学 原创 🙉
🏅 欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📆生活明朗,万物可爱,人间值得,未来可期!✨
----❤️-----❤️-----❤️-----❤️-----❤️-----❤️-----❤️-----
链表是什么?
链表是一种在存储单元上非连续、非顺序的存储结构。数据元素的逻辑顺序是通过链表中的指针链接次序实现。链表是由一系列的结点组成,结点可以在运行时动态生成。每个结点包含两部分:数据域与指针域。数据域存储数据元素,指针域存储下一结点的指针。
链表使用场景
链表的存储单元不是连续的,使用指针指向下一个元素,所以链表写操作非常的快,所以在写操作非常多的场景使用链表,那些排行榜,竞价平台的底层就是使用链表优化的。
单链表
单向链表也叫单链表,是链表中最简单的形式,它的每个节点包含两个域,一个信息域(元素域)和一个链接域。这个链接指向链表中的下一个节点,而最后一个节点的链接域则指向一个空值。
head 保存首地址,item 存储数据,next 指向下一结点地址。
python实现单链表
class LinkedNode:
# 链表节点
def __init__(self, val):
self.val = val
self.next = None
class SinglyLinkedList:
""" 单链表
is_empty: 判断链表是否为空
insert: 头插法
len: 长度
delete: 删除链表头
loop: 遍历
reverse: 反转链表 交换赋值
"""
def __init__(self):
self.__head = None
def is_empty(self):
return self.__head is None
def insert(self, val):
node = LinkedNode(val)
# 判断是否存在头结点
if self.__head:
node.next = self.__head
self.__head = node
def len(self):
cur = self.__head
count = 0
while cur:
count += 1
cur = cur.next
return count
def delete(self):
cur = self.__head
if self.__head:
self.__head = self.__head.next
cur.next = None
return cur
def loop(self):
cur = self.__head
while cur:
print(cur.val)
cur = cur.next
def reverse(self):
cur, prev = self.__head, None
while cur:
cur.next, prev, cur = prev, cur, cur.next
self.__head = prev
双链表
双向链表也指双链表,是链表的一种。它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。
class LinkedNode:
# 双向链表节点
def __init__(self, item):
self.item = item
self.next = None
self.prev = None
class DoubleLinkedList:
"""双向链表
is_empty: 判断链表是否为空
size: 返回链表大小
search: 查询元素 0不存在
add: 头部插入元素
append: 尾部添加元素
insert: 任意位置插入
remove: 移除元素
loop: 循环打印链表 输出list
reverse: 反转链表
"""
def __init__(self):
self.__head = None
@property
def is_empty(self):
return self.__head is None
@property
def size(self):
cur = self.__head
count = 0
while cur:
count += 1
cur = cur.next
return count
def search(self, item):
cur = self.__head
while cur:
if cur.item == item:
return 1
cur = cur.next
return 0
def add(self, item):
"""
若链表为空 将node赋值给head
链表不为空
将node的next属性指向头结点head
将头结点的prev属性指向 node
将node赋值给head
"""
node = LinkedNode(item)
if self.is_empty:
self.__head = node
else:
node.next = self.__head
self.__head.prev = node
self.__head = node
def append(self, item):
node = LinkedNode(item)
if self.is_empty:
self.__head = node
else:
cur = self.__head
while cur.next:
cur = cur.next
cur.next = node
node.prev = cur
def insert(self, pos: int, item):
if pos <= 0:
self.add(item)
elif pos > self.size - 1:
self.append(item)
else:
node = LinkedNode(item)
cur = self.__head
count = 0
# 移动到指定的前一位置
while count < pos - 1:
count += 1
cur = cur.next
node.prev = cur
node.next = cur.next
cur.next = node
@property
def loop(self):
items = []
cur = self.__head
while cur:
items.append(cur.item)
cur = cur.next
return items
def remove(self, item):
""" 移除元素
判断头部是否是要移除的元素
判断除头部外的元素
"""
if self.is_empty:
return 0
else:
cur = self.__head
if cur.item == item:
if cur.next:
self.__head = None
else:
cur.next.prev = None
self.__head = cur.next
return 1
while cur:
if cur.item == item:
cur.prev.next = cur.prev
break
cur = cur.next
def reverse(self):
"""
当链表为非空的时候,需要执行相应反转的操作
# 将头节点保存在current中
# 当链表为非空的时候,需要执行相应反转的操作
# 分别将相邻的两个节点的前驱后继关系进行反转
# 将下一个节点保存在next_node中
# 将下一个节点保存在next_node中
# 尾节点的前驱应指向原本的后继
"""
prev = None
cur = self.__head
while cur:
next = cur.next # 保存下一节点
cur.next = prev # 头节点反转后,成为尾节点,next指向None
cur.prev = next # 尾节点指向上一个
# prev cur 向后移动
prev = cur
cur = next
self.__head = prev # 尾节点处理
小结
数组和链表是一切数据结构的类型,我们平常使用较多的是list,但list并不是万能的,所以我们也要掌握链表,和list一样,我们也可以封装一些方法来操作链表,上面是简单的封装的几种,根据业务场景选择即可!