python中的链表

在 Python 中,链表不是内置的数据结构,但可以通过类的方式实现自定义链表。以下是链表在刷算法题中常用的语法和操作方法。


1. 定义链表节点

链表节点是一个包含值和指向下一个节点的指针的结构:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val  # 节点值
        self.next = next  # 指向下一个节点的指针

2. 常见链表操作

1) 创建链表

从列表创建链表:

def create_linked_list(values):
    if not values:
        return None
    head = ListNode(values[0])
    current = head
    for val in values[1:]:
        current.next = ListNode(val)
        current = current.next
    return head

2) 遍历链表

从头节点遍历到尾节点:

def print_linked_list(head):
    current = head
    while current:
        print(current.val, end=" -> ")
        current = current.next
    print("None")

3) 插入节点

在链表中间插入新节点:

def insert_node(head, position, value):
    new_node = ListNode(value)
    if position == 0:  # 插入头节点
        new_node.next = head
        return new_node
    current = head
    for _ in range(position - 1):
        if current is None:
            raise IndexError("Position out of bounds")
        current = current.next
    new_node.next = current.next
    current.next = new_node
    return head

4) 删除节点

删除指定位置的节点:

def delete_node(head, position):
    if position == 0:  # 删除头节点
        return head.next
    current = head
    for _ in range(position - 1):
        if current is None or current.next is None:
            raise IndexError("Position out of bounds")
        current = current.next
    current.next = current.next.next
    return head

5) 翻转链表

原地翻转链表:

def reverse_linked_list(head):
    prev = None
    current = head
    while current:
        next_node = current.next  # 保存下一个节点
        current.next = prev  # 当前节点指向前一个节点
        prev = current  # 更新前一个节点
        current = next_node  # 移动到下一个节点
    return prev  # 返回新的头节点

3. 算法题中常用链表语法

1) 双指针

  • 快慢指针:寻找链表中点、判断是否有环。
def has_cycle(head):
    slow = fast = head
    while fast and fast.next:
        slow = slow.next
        fast = fast.next.next
        if slow == fast:
            return True
    return False
  • 两个指针相遇:判断链表是否有交点。
def get_intersection_node(headA, headB):
    if not headA or not headB:
        return None
    p1, p2 = headA, headB
    while p1 != p2:
        p1 = p1.next if p1 else headB
        p2 = p2.next if p2 else headA
    return p1

2) 倒序处理

  • 找到链表倒数第 n 个节点,使用快慢指针:
def remove_nth_from_end(head, n):
    dummy = ListNode(0, head)
    slow = fast = dummy
    for _ in range(n):
        fast = fast.next
    while fast.next:
        slow = slow.next
        fast = fast.next
    slow.next = slow.next.next
    return dummy.next

3) 使用递归

  • 链表递归解法,适合逆序输出等场景:
def reverse_print(head):
    if head:
        reverse_print(head.next)
        // 对head.val值进行操作

4) 合并链表

  • 合并两个有序链表:
def merge_two_lists(list1, list2):
    dummy = ListNode(-1)
    current = dummy
    while list1 and list2:
        if list1.val < list2.val:
            current.next = list1
            list1 = list1.next
        else:
            current.next = list2
            list2 = list2.next
        current = current.next
    current.next = list1 if list1 else list2
    return dummy.next

5) k 组翻转

  • 分组翻转链表,常用分段处理:
def reverse_k_group(head, k):
    dummy = ListNode(0)
    dummy.next = head
    pre = dummy
    while True:
        tail = pre
        for _ in range(k):
            tail = tail.next
            if not tail:
                return dummy.next
        nex = tail.next
        head, tail = reverse(head, tail)
        pre.next = head
        tail.next = nex
        pre = tail
        head = tail.next

4. 技巧总结

  1. 哑节点(Dummy Node):简化头节点处理,减少边界条件判断。
  2. 双指针:灵活移动指针解决链表长度相关问题,如快慢指针、相遇指针。
  3. 递归:自然表达链表的递归结构,适合逆序操作或链表分治。
  4. 分段处理:将链表分块操作,常用于分组翻转或批量处理。

通过这些基础语法和模板,刷算法题中的链表问题会更加得心应手。

posted @ 2025-01-06 16:59  清澈的澈  阅读(136)  评论(0)    收藏  举报