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

news2024/11/17 21:26:14

文章目录

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

🍋引言

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

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

🍋什么是单链表?

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

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

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

🍋单链表的基本操作

  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() 方法来显示链表的内容。

运行结果如下
在这里插入图片描述

🍋练习题

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

题目:设计一个递归算法,删除不带头结点的单链表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),用于打印链表的内容,以便在删除操作后验证链表的状态。

🍋总结

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

请添加图片描述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1032729.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot财务管理系统springboot006

大家好✌!我是CZ淡陌。一名专注以理论为基础实战为主的技术博主,将再这里为大家分享优质的实战项目,本人在Java毕业设计领域有多年的经验,陆续会更新更多优质的Java实战项目,希望你能有所收获,少走一些弯路…

【zabbix监控三】zabbix之部署代理服务器

一、部署代理服务器 分布式监控的作用 分担server的几种式压力解决多机房之间的网络延时问题 1、搭建proxy主机 192.168.88.50 关闭防火墙和安全机制,修改主机名 设置 zabbix 的下载源,按照 zabbix-proxy rpm -ivh \ https://mirrors.aliyun.com/zab…

01-Maven入门

1 Maven简介 1.1 Maven是什么 Maven 是一个用于构建和管理 Java 项目的工具。它提供了一种标准化的项目结构和构建流程,可以自动化地处理项目的依赖管理、编译、测试、打包和部署等任务。 Maven 使用一个基于 XML 的配置文件(pom.xml)来描…

【C++面向对象侯捷】12.虚函数与多态 | 13.委托相关设计【设计模式 经典做法,类与类之间关联起来,太妙了,不断的想,不断的写代码】

文章目录 12.虚函数与多态举例:委托 继承【观察者模式】13.委托相关设计Composite 组合模式Prototype 原型模式 12.虚函数与多态 纯虚函数 一定要 子类重新定义的 继承和复合 关系下的构造和析构 举例:委托 继承【观察者模式】 13.委托相关设计 问题…

建材行业微信小程序开发实战经验分享

随着互联网的迅猛发展,电子商务成为了人们日常购物的主要方式之一。而微信小程序的兴起更是为商家提供了一个全新的线上销售渠道。在建筑材料选购领域,开发一个微信小程序商城平台能够有效地提升用户的购物体验和商家的销售效益。 为了实现建筑材料选购平…

Android studio中如何下载sdk

打开 file -> settings 这个页面, 在要下载的 SDK 前面勾上, 然后点 apply 在 platforms 中就可以看到下载好的 SDK: Android SDK目录结构详细介绍可以参考这篇文章: 51CTO博客- Android SDK目录结构

OpenAI ChatGPT API 文档之 Embedding

译者注: Embedding 直接翻译为嵌入似乎不太恰当,于是问了一下 ChatGPT,它的回复如下: 在自然语言处理和机器学习领域,"embeddings" 是指将单词、短语或文本转换成连续向量空间的过程。这个向量空间通常被称…

Python程序设计实例 |爬取网络中的小说

网络文学是新世纪我国流行文化中的重要领域,年轻人对网络小说更是有着广泛的喜爱。本文以抓取网络小说正文为例编写一个简单、实用的爬虫脚本。 01、分析网页 很多人在阅读网络小说时都喜欢本地阅读,换句话说就是把小说下载到手机或者其他移动设备上阅读…

TQ210-Bootloader-Uboot(LTS)

Bootloader的作用 Bootloader是位于计算机系统启动过程中的程序,它的主要作用是将操作系统从磁盘等外部存储介质加载到计算机内存中,并启动操作系统执行。Bootloader通常包括硬件初始化、自检、异常处理和启动操作系统等功能。它是计算机系统中非常重要…

Mac电脑系统怎么样才能干干净净地卸载应用程序?

Mac系统怎么样才能干干净净地卸载应用程序,不留下隐私数据和用户信息呢?如果有方法的话,那么该方法对于Mac电脑小白是否友好呢? CleanMyMac就是一款用于清理Mac系统下应用程序的一款清理工具,其内置了应用程序的安全卸…

第二证券:智能网联汽车产业迎催化 容量电价政策出台可期

昨日,A股延续调整态势,沪指失守3100点,深成指跌破10000点大关,创业板跌约1%再创阶段新低;两市成交额保持在地量水平,再创年内新低。到收盘,沪指跌0.77%报3084.7点,深成指跌0.9%报998…

速卖通新品如何推广,速卖通的推广渠道有哪些?——站斧浏览器

速卖通的推广渠道非常多样化,卖家可以根据自己的需求和预算选择合适的渠道来推广产品,提高曝光度和销售量,能够有效地提高产品的知名度和信任度。 速卖通新品如何推广? 速卖通上有数以百万计的卖家,每天都有大量的新…

批量寄件教程

快递行业的发展,和企业之间其实是正向的影响。为什么这么说呢?企业因公寄件,能为快递公司贡献一定寄件量,而快递行业的发展,不管是运输速度的提升,服务质量的提高,都能为企业的发展提供帮助&…

气膜建筑在施工工期方面的优势

充气膜建筑基础处理简单,迁移的损耗非常小,拆装方便,可快速安装,快速拆卸,可以很容易地建成季节性建筑,解决露天场馆因为“雨、晒、冷、雪”等导致部分时间不能营业的难题。 气膜建筑的柔性特点及其简约性使…

Stable Diffusion WebUI插件posex安装以及无法使用完美解决办法汇总

posex是一个很好用的3Dopenpose编辑器。 我们只需要去官网找到源码就可以查看其用法。 对于安装大家应该都知道怎么去安装。 1. 如何安装 (1)一体包安装方式 类似于秋叶一体包直接在webui界面搜索posex就可以直接install。 最新版本好像已经取消了。 (2)手动安装方式…

记一次MySQL安装过程中遇到的问题

由于太久没用MySQL,今天在重装MySQL时遇到一个问题,被卡了近2个小时。。。。。。 由于我本人原先安装过MySQL,所以在重装的时候必须要先卸载原先的MySQL。 下面先给出正确的卸载流程(作者就是在卸载的时候操作失误导致安装过程被…

Python灰帽编程——定制EXP之RCE

文章目录 定制EXP之RCE1. 常见模块介绍1.1 base641.1.1 base64 编码1.1.2 base64 解码 1.2 string 2. 常规 EXP 编写2.1 phpstudy_2016-2018_rce2.1.1 漏洞利用脚本2.1.2 进阶脚本 2.2 SQL 注入 EXP2.2.1 布尔盲注2.2.2 延时注入 2.3 metinfo_5.0.4 EXP编写2.3.1 SQL注入漏洞 3…

【Linux操作系统教程】用户管理与权限管理你真的懂了吗(三)

😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊 座右铭:不想…

早餐与风景

来吧,我用流水账描述下这一天。 时维九月,北京的早上有点冷,因为今天有个市场活动要去支撑,按照会议时间的要求,我需要在早上7点半就赶到会场,所以昨天晚上我加班到凌晨处理完了今天要给出去的材料&#xf…

ArrayList 的自动扩容机制

触发扩容 ArrayList 是一个数组结构的存储容器,默认情况下,数组的长度是 10 当然我们也可以在构建 ArrayList 对象的时候自己指定初始长度。随着在程序里面不断的往 ArrayList 中添加数据,当添加的数据达到 10 个的时候,ArrayLis…