本文目录导读:

我来详细解释Python中链表的实现,包括单链表和双链表的基本操作。
单链表的实现
节点类定义
class ListNode:
"""链表节点类"""
def __init__(self, val=0, next=None):
self.val = val # 节点值
self.next = next # 指向下一个节点
class LinkedList:
"""单链表类"""
def __init__(self):
self.head = None # 头节点
self.size = 0 # 链表长度
基本操作实现
class LinkedList:
def __init__(self):
self.head = None
self.size = 0
def is_empty(self):
"""判断链表是否为空"""
return self.head is None
def get_length(self):
"""获取链表长度"""
return self.size
def add_at_head(self, val):
"""在头部添加节点"""
new_node = ListNode(val)
new_node.next = self.head
self.head = new_node
self.size += 1
def add_at_tail(self, val):
"""在尾部添加节点"""
new_node = ListNode(val)
if self.is_empty():
self.head = new_node
else:
current = self.head
while current.next:
current = current.next
current.next = new_node
self.size += 1
def add_at_index(self, index, val):
"""在指定位置添加节点"""
if index < 0 or index > self.size:
return False
if index == 0:
self.add_at_head(val)
return True
new_node = ListNode(val)
current = self.head
# 找到插入位置的前一个节点
for _ in range(index - 1):
current = current.next
new_node.next = current.next
current.next = new_node
self.size += 1
return True
def delete_at_index(self, index):
"""删除指定位置的节点"""
if index < 0 or index >= self.size or self.is_empty():
return False
if index == 0:
self.head = self.head.next
else:
current = self.head
for _ in range(index - 1):
current = current.next
current.next = current.next.next
self.size -= 1
return True
def get(self, index):
"""获取指定位置的节点值"""
if index < 0 or index >= self.size:
return None
current = self.head
for _ in range(index):
current = current.next
return current.val
def find(self, val):
"""查找值第一次出现的位置"""
current = self.head
index = 0
while current:
if current.val == val:
return index
current = current.next
index += 1
return -1
def print_list(self):
"""打印链表"""
current = self.head
result = []
while current:
result.append(str(current.val))
current = current.next
print(" -> ".join(result))
使用示例
# 创建链表 ll = LinkedList() # 添加元素 ll.add_at_head(1) # 1 ll.add_at_tail(3) # 1 -> 3 ll.add_at_index(1, 2) # 1 -> 2 -> 3 # 打印链表 ll.print_list() # 输出: 1 -> 2 -> 3 # 获取元素 print(ll.get(1)) # 输出: 2 # 查找元素位置 print(ll.find(3)) # 输出: 2 # 删除元素 ll.delete_at_index(1) # 1 -> 3 ll.print_list() # 输出: 1 -> 3
双链表的实现
class DoubleListNode:
"""双链表节点类"""
def __init__(self, val=0, prev=None, next=None):
self.val = val
self.prev = prev
self.next = next
class DoublyLinkedList:
"""双链表类"""
def __init__(self):
self.head = None
self.tail = None
self.size = 0
def add_at_head(self, val):
"""在头部添加节点"""
new_node = DoubleListNode(val)
if self.is_empty():
self.head = new_node
self.tail = new_node
else:
new_node.next = self.head
self.head.prev = new_node
self.head = new_node
self.size += 1
def add_at_tail(self, val):
"""在尾部添加节点"""
new_node = DoubleListNode(val)
if self.is_empty():
self.head = new_node
self.tail = new_node
else:
new_node.prev = self.tail
self.tail.next = new_node
self.tail = new_node
self.size += 1
def delete_node(self, node):
"""删除指定节点"""
if not node:
return
# 处理前驱节点
if node.prev:
node.prev.next = node.next
else:
self.head = node.next
# 处理后继节点
if node.next:
node.next.prev = node.prev
else:
self.tail = node.prev
self.size -= 1
def print_forward(self):
"""从前向后打印"""
current = self.head
result = []
while current:
result.append(str(current.val))
current = current.next
print(" -> ".join(result))
def print_backward(self):
"""从后向前打印"""
current = self.tail
result = []
while current:
result.append(str(current.val))
current = current.prev
print(" <- ".join(result))
def is_empty(self):
return self.head is None
常见链表算法示例
反转链表
def reverse_linked_list(head: ListNode) -> ListNode:
"""反转单链表"""
prev = None
current = head
while current:
next_temp = current.next # 保存下一个节点
current.next = prev # 指向前一个节点
prev = current # 移动prev
current = next_temp # 移动current
return prev # prev是新的头节点
# 使用示例
def test_reverse():
ll = LinkedList()
for i in range(1, 6):
ll.add_at_tail(i)
print("原链表:", end=" ")
ll.print_list() # 1 -> 2 -> 3 -> 4 -> 5
# 反转链表
ll.head = reverse_linked_list(ll.head)
print("反转后:", end=" ")
ll.print_list() # 5 -> 4 -> 3 -> 2 -> 1
检测环
def has_cycle(head: ListNode) -> bool:
"""检测链表是否有环(快慢指针法)"""
if not head or not head.next:
return False
slow = head
fast = head.next
while slow != fast:
if not fast or not fast.next:
return False
slow = slow.next
fast = fast.next.next
return True
# 创建有环链表
def create_cycle_list():
"""创建一个有环的链表 1->2->3->4->5->3"""
head = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(4)
node5 = ListNode(5)
head.next = node2
node2.next = node3
node3.next = node4
node4.next = node5
node5.next = node3 # 创建环
return head
# 测试
head = create_cycle_list()
print(has_cycle(head)) # 输出: True
合并两个有序链表
def merge_two_lists(l1: ListNode, l2: ListNode) -> ListNode:
"""合并两个有序链表"""
dummy = ListNode(0) # 虚拟头节点
current = dummy
while l1 and l2:
if l1.val <= l2.val:
current.next = l1
l1 = l1.next
else:
current.next = l2
l2 = l2.next
current = current.next
# 连接剩余部分
current.next = l1 if l1 else l2
return dummy.next
# 使用示例
def test_merge():
# 创建有序链表1: 1->3->5
l1 = LinkedList()
l1.add_at_tail(1)
l1.add_at_tail(3)
l1.add_at_tail(5)
# 创建有序链表2: 2->4->6
l2 = LinkedList()
l2.add_at_tail(2)
l2.add_at_tail(4)
l2.add_at_tail(6)
# 合并
merged_head = merge_two_lists(l1.head, l2.head)
# 打印合并结果
result = LinkedList()
result.head = merged_head
print("合并后:", end=" ")
result.print_list() # 1 -> 2 -> 3 -> 4 -> 5 -> 6
实际应用案例
class LRUCache:
"""LRU缓存(使用双向链表+哈希表)"""
def __init__(self, capacity: int):
self.capacity = capacity
self.cache = {} # key -> node
self.head = DoubleListNode(0, 0) # 虚拟头节点
self.tail = DoubleListNode(0, 0) # 虚拟尾节点
self.head.next = self.tail
self.tail.prev = self.head
def _remove_node(self, node):
"""移除节点"""
node.prev.next = node.next
node.next.prev = node.prev
def _add_to_head(self, node):
"""将节点添加到头部"""
node.next = self.head.next
node.prev = self.head
self.head.next.prev = node
self.head.next = node
def get(self, key: int) -> int:
"""获取缓存值"""
if key in self.cache:
node = self.cache[key]
self._remove_node(node)
self._add_to_head(node)
return node.val
return -1
def put(self, key: int, value: int) -> None:
"""放入缓存"""
if key in self.cache:
node = self.cache[key]
node.val = value
self._remove_node(node)
self._add_to_head(node)
else:
if len(self.cache) >= self.capacity:
# 移除最久未使用的节点
lru_node = self.tail.prev
self._remove_node(lru_node)
del self.cache[lru_node.key]
new_node = DoubleListNode(key, value)
self.cache[key] = new_node
self._add_to_head(new_node)
# 使用LRU缓存
lru = LRUCache(2)
lru.put(1, 1) # 缓存:{1=1}
lru.put(2, 2) # 缓存:{1=1, 2=2}
print(lru.get(1)) # 输出: 1
lru.put(3, 3) # 移除key 2,缓存:{1=1, 3=3}
print(lru.get(2)) # 输出: -1
注意事项
- 内存管理:Python自动管理内存,但删除节点时要断开引用
- 边界处理:注意空链表、单节点链表的特殊情况
- 循环引用:双链表可能有循环引用,注意gc处理
- 性能考虑:链表插入删除快(O(1)),但查找慢(O(n))
链表在Python中虽然不是最常用的数据结构(列表已经很强大了),但在需要频繁插入删除、不确定存储大小时,链表仍然是一个很好的选择。