Python03 链表的用法

在 Python 中,链表并不是内置的数据结构,但可以通过定义类来实现链表。链表是一种常见的数据结构,它由一系列节点组成,每个节点包含数据部分和指向下一个节点的指针。

以下是链表的基本用法,包括定义链表节点类、创建链表、插入节点、删除节点、遍历链表等操作:

1. 定义链表节点类

链表的每个节点通常包含两个部分:数据(data)和指向下一个节点的指针(next)。

python 复制代码
class ListNode:
    def __init__(self, data):
        self.data = data  # 节点的数据
        self.next = None  # 指向下一个节点的指针

2. 创建链表

可以通过手动创建节点并连接它们来构建链表。

python 复制代码
# 创建链表节点
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)

# 连接节点
node1.next = node2
node2.next = node3

# 链表的头节点
head = node1

3. 链表的遍历

从头节点开始,通过 next 指针逐个访问链表中的每个节点。

python 复制代码
def print_linked_list(head):
    current = head
    while current:
        print(current.data, end=" -> ")
        current = current.next
    print("None")

# 测试
print_linked_list(head)  # 输出:1 -> 2 -> 3 -> None

4. 插入节点

在链表头部插入节点

python 复制代码
def insert_at_head(head, data):
    new_node = ListNode(data)
    new_node.next = head
    return new_node

# 测试
head = insert_at_head(head, 0)
print_linked_list(head)  # 输出:0 -> 1 -> 2 -> 3 -> None

在链表尾部插入节点

python 复制代码
def insert_at_tail(head, data):
    new_node = ListNode(data)
    if not head:  # 如果链表为空
        return new_node
    current = head
    while current.next:  # 找到链表的最后一个节点
        current = current.next
    current.next = new_node
    return head

# 测试
head = insert_at_tail(head, 4)
print_linked_list(head)  # 输出:0 -> 1 -> 2 -> 3 -> 4 -> None

在链表中间插入节点

python 复制代码
def insert_after_node(head, prev_node_data, data):
    new_node = ListNode(data)
    current = head
    while current and current.data != prev_node_data:
        current = current.next
    if current:  # 找到了要插入位置的前一个节点
        new_node.next = current.next
        current.next = new_node

# 测试
head = insert_after_node(head, 2, 2.5)
print_linked_list(head)  # 输出:0 -> 1 -> 2 -> 2.5 -> 3 -> 4 -> None

5. 删除节点

删除链表头部节点

python 复制代码
def delete_head(head):
    if not head:  # 如果链表为空
        return None
    return head.next

# 测试
head = delete_head(head)
print_linked_list(head)  # 输出:1 -> 2 -> 2.5 -> 3 -> 4 -> None

删除链表中间或尾部节点

python 复制代码
def delete_node(head, data):
    if not head:  # 如果链表为空
        return None
    if head.data == data:  # 如果要删除的是头节点
        return head.next
    current = head
    while current.next and current.next.data != data:
        current = current.next
    if current.next:  # 找到了要删除的节点
        current.next = current.next.next
    return head

# 测试
head = delete_node(head, 2.5)
print_linked_list(head)  # 输出:1 -> 2 -> 3 -> 4 -> None

6. 获取链表长度

python 复制代码
def get_length(head):
    length = 0
    current = head
    while current:
        length += 1
        current = current.next
    return length

# 测试
print(get_length(head))  # 输出:4

7. 反转链表

python 复制代码
def reverse_linked_list(head):
    prev = None
    current = head
    while current:
        next_node = current.next  # 保存下一个节点
        current.next = prev  # 反转当前节点的指针
        prev = current  # 移动prev和current
        current = next_node
    return prev

# 测试
head = reverse_linked_list(head)
print_linked_list(head)  # 输出:4 -> 3 -> 2 -> 1 -> None

8. 使用链表实现栈和队列

链表实现栈

栈是后进先出(LIFO)的数据结构,可以用链表的头部作为栈顶。

python 复制代码
class Stack:
    def __init__(self):
        self.head = None

    def push(self, data):
        new_node = ListNode(data)
        new_node.next = self.head
        self.head = new_node

    def pop(self):
        if not self.head:
            return None
        data = self.head.data
        self.head = self.head.next
        return data

    def is_empty(self):
        return self.head is None

# 测试
stack = Stack()
stack.push(1)
stack.push(2)
stack.push(3)
print(stack.pop())  # 输出:3
print(stack.pop())  # 输出:2
print(stack.is_empty())  # 输出:False

链表实现队列

队列是先进先出(FIFO)的数据结构,可以用链表的头部作为队头,尾部作为队尾。

python 复制代码
class Queue:
    def __init__(self):
        self.head = None
        self.tail = None

    def enqueue(self, data):
        new_node = ListNode(data)
        if not self.head:
            self.head = new_node
            self.tail = new_node
        else:
            self.tail.next = new_node
            self.tail = new_node

    def dequeue(self):
        if not self.head:
            return None
        data = self.head.data
        self.head = self.head.next
        if not self.head:  # 如果队列为空,更新尾指针
            self.tail = None
        return data

    def is_empty(self):
        return self.head is None

# 测试
queue = Queue()
queue.enqueue(1)
queue.enqueue(2)
queue.enqueue(3)
print(queue.dequeue())  # 输出:1
print(queue.dequeue())  # 输出:2
print(queue.is_empty())  # 输出:False

链表在 Python 中虽然不是内置数据结构,但通过自定义类可以灵活地实现各种链表操作,适用于需要动态数据结构的场景,如内存分配、图的邻接表表示等。

相关推荐
Aurora_wmroy6 分钟前
算法竞赛备赛——【数据结构】链表
数据结构·c++·算法·链表·蓝桥杯
ん贤21 分钟前
单调栈详解【C/C++】
数据结构·c++·算法·贪心算法·单调栈
空雲.35 分钟前
ABC 373
算法·深度优先
点云登山者2 小时前
登山第二十梯:无人机实时自主探索——我是一只小小小鸟
算法·计算机视觉·机器人·无人机·路径规划·激光点云·自主探索
大胆飞猪2 小时前
优选算法训练篇08--力扣15.三数之和(难度中等)
算法·leetcode
<但凡.3 小时前
C++修炼:内存管理
c++·算法
tpoog3 小时前
[贪心算法]买卖股票的最佳时机 && 买卖股票的最佳时机Ⅱ && K次取反后最大化的数组和 && 按身高排序 && 优势洗牌(田忌赛马)
算法·贪心算法
大模型铲屎官3 小时前
支持向量机(SVM):从入门到精通的机器学习利器
开发语言·人工智能·深度学习·算法·机器学习·llm·支持向量机(svm)
小檀6104 小时前
C语言基础08
c语言·算法·排序算法
进击的jerk4 小时前
力扣45.跳跃游戏
开发语言·c++·算法·leetcode·游戏