# 方法2:链式创建 head = ListNode(1, ListNode(2, ListNode(3)))
# 方法3:从列表创建 defcreate_linked_list(arr): ifnot arr: returnNone head = ListNode(arr[0]) current = head for val in arr[1:]: current.next = ListNode(val) current = current.next return head
head = create_linked_list([1, 2, 3, 4, 5]) # 比较链表某个元素的大小 if head.val == head.next.val # 比较两个位置是不是链表中的同一位置 if head.nextis head
遍历链表
1 2 3 4 5 6 7 8
defprint_linked_list(head): current = head while current: print(current.val, end=" → ") current = current.next print("None")
# 在结尾插入 definsert_at_end(head, val): new_node = ListNode(val) ifnot head: return new_node current = head while current.next: current = current.next current.next = new_node return head
# 在指定位置插入 definsert_at_position(head, val, position): if position == 0: return insert_at_beginning(head, val) new_node = ListNode(val) current = head for _ inrange(position - 1): ifnot current: raise IndexError("位置超出范围") current = current.next new_node.next = current.next current.next = new_node return head
# 删除第一个值为val的节点 defdelete_node(head, val): ifnot head: returnNone # 如果要删除的是头节点 if head.val == val: return head.next current = head while current.nextand current.next.val != val: current = current.next if current.next: current.next = current.next.next return head
# 删除指定位置的节点 defdelete_at_position(head, position): ifnot head: returnNone if position == 0: return head.next current = head for _ inrange(position - 1): ifnot current.next: raise IndexError("位置超出范围") current = current.next if current.next: current.next = current.next.next return head
链表 vs 数组
操作
数组
链表
访问第i个元素
O(1)
O(n)
在开头插入
O(n)
O(1)
在结尾插入
O(1)*
O(n)
在中间插入
O(n)
O(1)
删除元素
O(n)
O(1)
内存使用
连续,较少
分散,每个节点多一个指针
缓存友好
是
否
*Python列表是动态数组,结尾插入平均O(1)
常见算法题示例
1. 反转链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defreverse_list(head): prev = None current = head while current: next_temp = current.next# 保存下一个节点 current.next = prev # 反转指针 prev = current # 移动prev current = next_temp # 移动current return prev # 新的头节点
# 1 → 2 → 3 → None # 变成 3 → 2 → 1 → None
2. 检测环
1 2 3 4 5 6 7 8 9 10 11 12 13 14
defhas_cycle(head): ifnot head ornot head.next: returnFalse slow = head # 慢指针,每次走一步 fast = head.next# 快指针,每次走两步 while slow != fast: ifnot fast ornot fast.next: returnFalse slow = slow.next fast = fast.next.next returnTrue
3. 合并两个有序链表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
defmerge_two_lists(l1, l2): 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 or l2 return dummy.next
4. 找中间节点
1 2 3 4 5 6 7 8 9
defmiddle_node(head): slow = fast = head while fast and fast.next: slow = slow.next fast = fast.next.next return slow # 奇数长度返回中间,偶数返回第二个中间节点
5. 判断是否有环形
1 2 3 4 5 6 7 8 9 10
# 如果有环的话,那么兔子和乌龟都会进入环中。这时用「相对速度」思考,乌龟不动,兔子相对乌龟每次只走一步,这样就可以看出兔子一定会和乌龟相遇了。 classSolution: defhasCycle(self, head: Optional[ListNode]) -> bool: slow = fast = head # 乌龟和兔子同时从起点出发 while fast and fast.next: slow = slow.next# 乌龟走一步 fast = fast.next.next# 兔子走两步 if fast is slow: # 兔子追上乌龟(套圈),说明有环 returnTrue returnFalse# 访问到了链表末尾,无环