1.1 🐏单链表:
单链表中的一个节点由 数据域(value/data) + 指针域(next) 组成,其中指针域指向下一个节点(即存放着下一个节点的地址),最后一个节点指针域指向为空。
1.2 🐺双链表
双链表中的一个节点由 数据域+ 两v指针域 组成,一个指针域指向上一个节点,一个指针域指向下一个节点(即存放上、下节点的地址),
头节点和尾节点中都有一个节点指针域指向为空。
1.3 🦊循环链表
循环列表:链表首尾节点相连
2.1 🐻链表存储方式
数组在内存中是连续分布
链表在内存中是非连续分布(散乱分布)
通过指针域将节点按顺序连接在一起
3.1 🐱链表定义
变量赋值,实际上是将node2所在内存中的地址复制给了node1的next属性,通过id(node1.next)来获取node2地址。
class ListNode:
def __init__(self, value):
self.val = value # 数据域,存储节点的数据
self.next = None # 指针域,存储指向下一个节点的地址
# 创建一个简单的单链表
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
# 变量赋值,实际上是将node2所在内存中的地址复制给了node1的next属性,通过id(node1.next)来获取node2地址。
node1.next = node2
node2.next = node3
# 遍历单链表并打印节点的数据
curr_node = node1 # 头节点
while curr_node: # 从头节点开始遍历
print(curr_node.val)
curr_node = curr_node.next # 指向下一个节点
4.1 🥛链表操作
4.1.1 删除节点
#---删除链表中的一个节点---#
class ListNode:
def __init__(self, value):
self.val = value
self.next = None
def delete_node(head, val):
# 如果头节点 head 的值就是要删除的值 val,则直接返回头节点的下一个节点 head.next,即删除头节点
if head.val == val:
return head.next
# 如果头节点 head 不是要删除的值,则从头节点 head 的下一个节点 head.next 开始查找
prev = head # prev是前一个节点,cur是当前节点
cur = head.next
# 循环条件:只要 cur 不为空且当前节点 cur 存储的数据不等于 val
while cur and cur.val != val: # cur 和 cur.val != val
prev, cur = cur, cur.next # 继续遍历下一个节点
# cur为空 或 cur 存储的数据等于 val, 删除节点
if cur:
prev.next = cur.next # 将前一个节点指针域和下一个节点地址连接在一起,去掉当前节点
return head # 通过头节点来找到这段链表的每个节点
4.1.2 添加节点
#---在链表尾部添加一个节点---#
class ListNode:
def __init__(self, val=0, next=None):
self.val = val # 存储节点的值
self.next = next # 存储指向下一个节点的引用
def add_node(head, val):
new_node = ListNode(val) # 创建新节点
# 如果头节点为空(原链表是空链表),直接返回新节点
if not head:
return new_node
# 头节点不为空,设置当前节点为头节点
cur = head
while cur.next: # 存在下一个节点,进入循环。
cur = cur.next # 找到下一个节点
cur.next = new_node # 在尾节点后面添加新节点
return head # 返回头节点