探索单链表数据结构:理解与实现

文章目录

  • 引言
  • 什么是单链表?
  • 单链表的基本操作
  • 单链表的实现
  • 练习题
  • 总结

引言

在计算机科学和数据结构中,链表是一种基本且重要的数据结构,用于存储和组织数据。单链表是其中最简单的一种形式,它由一系列节点组成,每个节点都包含一个数据元素和一个指向下一个节点的指针。在这篇博客中,我们将深入探讨单链表的工作原理以及如何用代码实现它。

最近在刷力扣的时候,发现链表这块挺重要的,所以来回忆回忆

什么是单链表?

单链表是一种线性数据结构,其中的节点按照线性顺序排列。每个节点都包含两个部分:

  • 数据元素:存储实际的数据。
  • 指针(或引用):指向下一个节点的位置。

这个简单的结构允许我们在链表中添加、删除和访问元素,而不需要像数组一样具有固定的大小。这使得链表在需要频繁插入和删除元素时非常有用。

单链表的基本操作

  1. 插入操作

要在单链表中插入一个新的节点,我们需要执行以下步骤:

  • 创建一个新的节点,并将要插入的数据存储在其中。
  • 将新节点的指针指向原链表中的下一个节点。
  • 更新前一个节点的指针,使其指向新节点。
  1. 删除操作

要删除链表中的节点,我们需要执行以下步骤:

  • 找到要删除的节点的前一个节点。
  • 更新前一个节点的指针,使其跳过要删除的节点,直接指向后一个节点。
  1. 访问操作
  • 要访问链表中的节点,我们可以从链表的头节点开始,依次遍历每个节点,直到找到目标节点或到达链表的末尾。

单链表的实现

# 创建一个节点类(Node),用于表示单链表的节点
class Node:
    def __init__(self, data):
        self.data = data  # 存储节点的数据
        self.next = None  # 存储指向下一个节点的指针,默认为None

# 创建一个单链表类(LinkedList)
class LinkedList:
    def __init__(self):
        self.head = None  # 初始化链表,头节点默认为None

    # 向链表中添加元素的方法
    def append(self, data):
        new_node = Node(data)  # 创建一个新的节点,将数据存储在其中
        if not self.head:  # 如果链表为空,将新节点设置为头节点
            self.head = new_node
            return
        current = self.head  # 从头节点开始遍历链表
        while current.next:  # 移动到链表的末尾
            current = current.next
        current.next = new_node  # 将新节点连接到链表的末尾

    # 显示链表内容的方法
    def display(self):
        current = self.head  # 从头节点开始遍历链表
        while current:  # 遍历整个链表
            print(current.data, end=" -> ")  # 打印当前节点的数据
            current = current.next  # 移动到下一个节点
        print("None")  # 链表结束后打印 "None" 表示结束

# 创建一个新的链表实例
my_linked_list = LinkedList()

# 向链表中添加元素
my_linked_list.append(1)
my_linked_list.append(2)
my_linked_list.append(3)

# 显示链表的内容
my_linked_list.display()

上述代码首先定义了两个类:Node 和 LinkedList。Node 类表示链表中的节点,每个节点包含一个数据元素和一个指向下一个节点的指针。LinkedList 类表示单链表,其中包含一个头节点,通过头节点可以访问整个链表。

在 LinkedList 类中,有两个主要方法:

  • append(data) 方法用于向链表中添加新的节点。它会创建一个新的节点并将其连接到链表的末尾。
  • display() 方法用于显示链表的内容。它会从头节点开始遍历链表,并打印每个节点的数据,直到链表结束。

最后,创建了一个 my_linked_list 实例,向链表中添加了三个元素(1、2 和 3),然后调用 display() 方法来显示链表的内容。

运行结果如下
探索单链表数据结构:理解与实现_第1张图片

练习题

这里我们选一道我考研时期做过的题

题目:设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
首先我们要明确这题的几种可能,尤为重要的是为空的可能,我记得我之前总是遗忘

  1. 如果链表为空,递归结束。
  2. 如果链表的头结点的值等于 x,则将头结点删除,并递归调用删除函数来处理剩余的链表(即调用函数自身)。
  3. 如果链表的头结点的值不等于 x,则保留头结点,并递归调用删除函数来处理剩余的链表。
class ListNode:
    def __init__(self, value):
        self.value = value
        self.next = None

def delete_nodes_with_value(head, x):
    # 递归终止条件:如果链表为空,直接返回
    if not head:
        return None
    
    # 递归处理剩余的链表
    head.next = delete_nodes_with_value(head.next, x)
    
    # 如果当前节点的值等于 x,则返回下一个节点,相当于删除了当前节点
    if head.value == x:
        return head.next
    
    return head

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

# 创建一个示例链表:1 -> 2 -> 3 -> 2 -> 4
node1 = ListNode(1)
node2 = ListNode(2)
node3 = ListNode(3)
node4 = ListNode(2)
node5 = ListNode(4)

node1.next = node2
node2.next = node3
node3.next = node4
node4.next = node5

print("原始链表:")
print_linked_list(node1)

x = 2
new_head = delete_nodes_with_value(node1, x)

print(f"删除值为 {x} 的节点后的链表:")
print_linked_list(new_head)

首先,我们定义了一个节点类 ListNode,该类用于表示链表的节点。每个节点有两个属性:value 用于存储节点的值,next 用于指向下一个节点。

接下来,我们定义了一个递归函数 delete_nodes_with_value(head, x),它接受链表的头节点 head 和要删除的值 x 作为参数。这个函数执行以下操作:

  • 首先,它检查递归的终止条件。如果链表为空(head 为 None),则递归结束,返回 None。
  • 否则,它递归调用自己,传递链表的下一个节点 head.next,以处理剩余的链表部分。
  • 在递归回溯时,它检查当前节点的值是否等于 x。如果相等,它将返回下一个节点 head.next,这相当于删除了当前节点。
  • 如果当前节点的值不等于 x,它将返回当前节点 head,保留当前节点,并继续处理下一个节点。

接下来,我们定义了一个辅助函数 print_linked_list(head),用于打印链表的内容,以便在删除操作后验证链表的状态。

总结

单链表是一个非常有用的数据结构,用于处理各种编程问题,包括数据存储、算法实现和数据检索。希望这个解释有助于你理解如何实现和使用单链表。

探索单链表数据结构:理解与实现_第2张图片

挑战与创造都是很痛苦的,但是很充实。

你可能感兴趣的:(数据结构,数据结构,python)