为了便于初学者更好地理解编程概念,我最近为俱乐部成员准备了一场培训,并为此编写了一些示例代码。这些代码不仅结构清晰,而且配有详尽的注释,帮助大家快速掌握核心要点。
在编写过程中,我还融入了一些个人在实践中积累的独特思路和技巧,旨在从不同角度启发学习者。相信通过阅读和实践这些内容,大家能够获得实质性的提升与启发。
# -*- coding : utf-8 -*-
"""
@author: 江南大学 —— 2025数据赋能俱乐部
@Description: 一个轻量、清晰且易扩展的Python双向链表实现
@Date: 2025-11-24 0:20
"""
# 双链表的节点类。下文用a、b、c表示节点,是为了增强大家对节点顺序的感知,不易出错
class Node: # 只需要记忆前三个函数
def __init__(self, val=None): # 默认val为空
self.val = val
self.pre = None # 初始为空
self.next = None # 初始为空
# 在当前节点的下一个位置插入 b 节点
def insert_next(self, b):
a, c = self, self.next # 先得到被新增节点的前、后节点,问题转化为在a、c之间插入b
b.pre, b.next = a, c # 先连接新线,对b的线进行赋值。b的前后应该是a和c
a.next, c.pre = b, b # 再连接旧线,对a的后线和c的前线进行赋值。a和c的中间是b
# 删除当前节点
def del_self(self):
a, c = self.pre, self.next # 先得到被删除节点的前、后节点,问题转化为直接连接a、c节点
a.next, c.pre = c, a # 直接连接a、c节点,a的后面应该是c,c的前面应该是a
######################################################################################
""" 问题转化开始 """
# 变式1:在当前节点的上一个位置插入 b 节点
def insert_pre(self, b):
# 直接调用上一个节点的后插函数
self.pre.insert_next(b)
# 变式2:删除下一个节点(需保证有下一个)
def del_next(self):
# 直接调用下一个节点的自删函数
self.next.del_self()
# 变式3:删除上一个节点(需保证有上一个)
def del_pre(self):
# 直接调用上一个节点的自删函数
self.pre.del_self()
# 变式4:在当前节点前面插入任意个values
def insert_values_pre(self, values): # values是一个列表,其元素是简单的值
# 先拿到当前节点
p = self # p是一个临时指针
# 不停地往p前面插,p不用动
for val in values:
p.insert_pre(Node(val)) # 需要用val生成一个新的节点,然后传进去
# 变式5:在当前节点后面插入任意个values
def insert_values_next(self, values): # values是一个列表,其元素是简单的值
# 直接调用下一个节点的任意插入函数
self.next.insert_values_pre(values)
# 变式6: 删除当前节点前面的n个节点(需要你自己保证不会删过头)
def del_pre_n(self, n):
# 先拿到当前节点
p = self # p是一个临时指针
# 不停地删除p前面的节点,p不用动
for _ in range(n):
p.del_pre()
# 变式7: 删除当前节点后面的n个节点(需要你自己保证不会删过头)
def del_next_n(self, n):
# 先拿到当前节点
p = self # p是一个临时指针
# 不停地删除p后面的节点,p不用动
for _ in range(n):
p.del_next()
# 变式8: 找到n个之后的节点(需要你自己保证后面有n个),然后返回
def find_next_n(self, n):
# 先拿到当前节点
p = self # p是一个临时指针
for _ in range(n):
# 不停地找下一个
p = p.next
return p
# 变式9:删除n个节点后的m个节点
def del_after_n_count_m(self, n, m):
# 先找n个节点后的节点
p = self.find_next_n(n)
# 直接删
p.del_next_n(m)
""" 问题转化结束 """
#######################################################################################
""" 下面2个是辅助工具函数 """
# 从head到tail打印当前链表(跳过哨兵)
def print_list(head, tail):
p = head.next # 跳过头结点
while p is not tail: # 下一个不是尾节点
print(p.val, end=" ")
p = p.next
print()
# 构造只有 head / tail 的空双链表
def build_empty_list():
head = Node() # head
tail = Node() # tail
head.next = tail # head --> tail
tail.pre = head # tail --> head
# 此时: head <--> tail
return head, tail
if __name__ == '__main__':
# ================== 用例1:基本插入 / 删除 ==================
print("== 用例1:基本插入 / 删除 ==")
head, tail = build_empty_list()
a = Node("A")
head.insert_next(a)
b = Node("B")
a.insert_next(b)
c = Node("C")
b.insert_next(c)
print("初始链表:")
print_list(head, tail) # A B C
b.del_self()
print("删除 B 后:")
print_list(head, tail) # A C
# ================== 用例2:前插 / 删前删后 ==================
print("\n== 用例2:前插 / 删前删后 ==")
head, tail = build_empty_list()
x = Node("X")
head.insert_next(x)
x.insert_pre(Node("L"))
x.insert_next(Node("R"))
print("前插 L,后插 R:")
print_list(head, tail) # L X R
x.del_pre()
print("删除前一个节点:")
print_list(head, tail) # X R
x.del_next()
print("删除后一个节点:")
print_list(head, tail) # X
# ================== 用例3:批量前插 / 后插 ==================
print("\n== 用例3:批量插入 ==")
head, tail = build_empty_list()
mid = Node("M")
head.insert_next(mid)
mid.insert_values_pre(["a", "b", "c"])
print("批量前插 a b c:")
print_list(head, tail) # a b c M
mid.insert_values_next(["x", "y"])
print("批量后插 x y:")
print_list(head, tail) # a b c M x y
# ================== 用例4:删除前 n 个 / 后 n 个 ==================
print("\n== 用例4:删除前 n / 后 n ==")
head, tail = build_empty_list()
head.insert_values_next([1, 2, 3, 4, 5, 6])
print("初始链表:")
print_list(head, tail) # 1 2 3 4 5 6
third = head.next.next.next # 第 3 个节点 val=3
third.del_pre_n(2)
print("删除 3 前面的 1、2:")
print_list(head, tail) # 3 4 5 6
third.del_next_n(1)
print("删除 3 后面的 4:")
print_list(head, tail) # 3 5 6
# ================== 用例5:find_next_n / del_after_n_count_m ==================
print("\n== 用例5:查找 + 组合删除 ==")
head, tail = build_empty_list()
head.insert_values_next(list("ABCDEFG"))
print("初始链表:")
print_list(head, tail) # A B C D E F G
first = head.next
target = first.find_next_n(2)
print("从 A 往后数 2 个节点(应为 C):", target.val)
first.del_after_n_count_m(2, 3)
print("删除 C 后的 D E F:")
print_list(head, tail) # A B C G