当前位置: 首页 > news >正文

链表理论基础

一、链表的基本知识

链表是一种特殊的数据结构,下面通过一个生活中的例子来帮助理解:想象你在银行办理业务时,首先需要抽号。每个顾客拿到号码后,会随意坐在一旁等待叫号。当叫到你时,你才会去办理业务。这里,抽到的号码就像是链表中的“节点”,每个顾客(节点)持有一个号码,并通过叫号顺序(指针)指向下一个顾客(节点)。整个过程就像是链表的遍历:每个节点通过“指针”连接下一个节点,直到最后一个顾客,指向为 NULL,表示结束。每位顾客坐的位置是无序的,但是办理业务时却是有序的,这表明他们在逻辑上有序的。

那么什么是链表?链表(Linked List)是一种线性数据结构,它由一系列节点(Node)组成,每个节点包含两部分:数据域(Data)和指向下一个节点的指针域(Next)。链表的特点是节点在内存中不是连续存储的,每个节点通过指针链接到下一个节点,从而形成一个链式结构。这些节点在逻辑上是有序的。

链表的入口节点称为链表的头结点也就是head。

单链表

 

二、循环链表

循环链表(Circular Linked List) 是一种链表变体,它与普通的链表(如单向链表、双向链表)最大的区别在于,最后一个节点的指针指向头节点,形成一个循环结构。这种结构可以是单向循环链表,也可以是双向循环链表。

循环链表可以用来解决约瑟夫环问题。

 

2.1循环链表的特点

  • 没有空指针(NULL):在普通的链表中,最后一个节点的 next 指针指向 NULL,表示链表的结束。而在循环链表中,最后一个节点的 next 指针指向头节点,形成一个闭环。
  • 遍历便利:循环链表的一个显著特点是可以从任意节点开始,循环遍历整个链表,无需担心链表的结束。通过一个指针就能遍历整个链表。
  • 适用于循环操作:循环链表适合用于需要循环往复访问元素的场景,例如:模拟游戏中的轮流操作、缓存数据的循环访问等。

2.2 循环链表的优势

  1. 无限循环遍历:由于链表是循环的,可以在遍历过程中无休止地循环遍历所有节点,适用于需要周期性或轮换访问数据的场景。
  2. 容易处理环状数据:在某些应用中(比如游戏、调度算法等),我们需要不断循环地访问数据,循环链表提供了自然的支持。
  3. 插入和删除:和普通链表一样,循环链表在插入和删除节点时也具有较高的灵活性,尤其是当操作发生在链表的开头或末尾时,不需要移动其他节点。

2.3 循环链表的缺点

  1. 指针操作复杂:循环链表在实现时需要特别注意指针的操作,尤其是在插入或删除节点时,要确保不会破坏循环结构。
  2. 不容易检测链表结束:由于循环链表没有NULL作为终止标志,遍历时必须依赖其他方式来判断是否回到了起始节点,从而避免陷入死循环。

2.4 应用场景

  1. 循环队列/缓冲区:在环形缓冲区中,数据是不断循环使用的,适合用循环链表来实现。
  2. 操作系统调度:某些操作系统的任务调度算法使用循环链表来实现轮询任务调度。
  3. 游戏中的回合制系统:如多人在线游戏中,玩家按顺序轮流行动,循环链表可用来存储玩家信息,保证轮流操作。

三、链表的存储方式

了解完链表的类型,再来说一说链表在内存中的存储方式。

数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。

链表是通过指针域的指针链接在内存中各个节点。

所以链表中的节点在内存中不是连续分布的 ,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。

如图所示:

 

这个链表起始节点为2, 终止节点为7, 各个节点分布在内存的不同地址空间上,通过指针串联在一起。 

四、链表的代码定义

接下来说一说链表的定义。

链表节点的定义,很多同学在面试的时候都写不好。

这是因为平时在刷leetcode的时候,链表的节点都默认定义好了,直接用就行了,所以同学们都没有注意到链表的节点是如何定义的。

而在面试的时候,一旦要自己手写链表,就写的错漏百出。

这里我给出C/C++的定义链表节点方式,如下所示:

// 单链表
struct ListNode {
    int val;  // 节点上存储的元素
    ListNode *next;  // 指向下一个节点的指针
    ListNode(int x) : val(x), next(NULL) {}  // 节点的构造函数
// ----------------------------------------------------------------
ListNode(int x) : val(x), next(NULL) {}代码解读
1. ListNode(int x)
这是构造函数的 函数声明部分。

ListNode 是结构体的名称,表示你正在定义一个 ListNode 类型的对象。
(int x) 是构造函数的参数,表示构造函数接收一个整数 x,通常这个 x 用来初始化节点的 val 字段。这个 x 只是构造函数的输入参数,用于给节点的 val 字段赋值。
2. : val(x), next(NULL)
这一部分是 构造函数的初始化列表。它在构造函数体执行之前先执行,主要用于初始化成员变量。

val(x):初始化 val 成员变量,将传入的参数 x 赋值给 val。即,x 的值会被传递给 val,从而在创建 ListNode 对象时,节点的 val 被初始化为 x。
next(NULL):初始化 next 成员变量,将 next 指针初始化为 NULL,表示当前节点没有指向下一个节点(即该节点是链表中的最后一个节点,或者尚未与其他节点连接)。
3. {}
这是构造函数的 空函数体,表示构造函数完成了所有初始化任务后不需要其他的操作。在这个例子中,所有初始化操作都通过初始化列表完成,因此函数体可以是空的。
整体解读
构造函数的作用:构造函数用于在创建 ListNode 类型的对象时自动初始化该对象的成员变量。此构造函数将 x 作为输入,赋值给 val,并将 next 初始化为 NULL,表示当前节点不连接任何其他节点。
};

C语言中的链表初始化

在C语言中,你需要手动管理结构体的初始化,例如:

struct ListNode {
    int val;
    struct ListNode* next;
};

struct ListNode* createNode(int x) {
    struct ListNode* newNode = (struct ListNode*)malloc(sizeof(struct ListNode));
    if (newNode) {
        newNode->val = x;
        newNode->next = NULL;
    }
    return newNode;
}

这里,C语言没有构造函数,所以我们需要通过显式的malloc和字段初始化来创建和初始化链表节点。每次创建节点时,都需要手动调用createNode函数来初始化节点。

五、链表的操作

5.1 添加节点 

5.2 删除节点

删除D节点,如图所示:

只要将C节点的next指针 指向E节点就可以了。

那有同学说了,D节点不是依然存留在内存里么?只不过是没有在这个链表里而已。

是这样的,所以在C++里最好是再手动释放这个D节点,释放这块内存。

其他语言例如Java、Python,就有自己的内存回收机制,就不用自己手动释放了。

可以看出链表的增添和删除都是O(1)操作,也不会影响到其他节点。

但是要注意,要是删除第五个节点,需要从头节点查找到第四个节点通过next指针进行删除操作,查找的时间复杂度是O(n)。

 六、性能分析

再把链表的特性和数组的特性进行一个对比,如图所示: 

普通数组在定义时长度是固定的,如果需要改变数组的长度,就必须重新定义一个新的数组【std::vector除外,这是动态数组】。相比之下,链表的长度是动态的,可以根据需要随时增减节点,非常适合数据量不确定、需要频繁增删但查询较少的场景。

相关文章:

  • Java并发编程面试题:并发工具类(10题)
  • [2/11]C#性能优化-不要使用空析构函数-每个细节都有示例代码
  • Windows和AD域提权枚举脚本及工具介绍
  • python-leetcode-乘积最大子数组
  • 【CI/CD】Jenkins + Docker +SpringCloud微服务项目持续集成
  • 项目总结nk
  • Android ObjectBox数据库使用与集成指南
  • Doris系列之基础使用
  • Magma:多模态 AI 智体的基础模型
  • DeepSeek 助力 Vue3 开发:打造丝滑的下拉选择框(Dropdown Select)
  • 数据结构——基于单链表创建通讯录
  • LangChain教程 - RAG - PDF问答
  • HarmonyOS+Django实现图片上传
  • AVFormatContext
  • Node.js v16 版本安装
  • 排序(数据结构篇)
  • YOLOv12 ——基于卷积神经网络的快速推理速度与注意力机制带来的增强性能结合
  • 百度觉醒,李彦宏渴望光荣
  • 浅析 Redis 分片集群 Cluster 原理、手动搭建、动态伸缩集群、故障转移
  • 《Spring Boot + MySQL高性能应用实战:性能优化技巧与最佳实践》
  • “中国神湖”加快放大资源规模!3亿美元换海外年产380万吨钾盐项目
  • 奥迪车加油时频繁“跳枪”维修两年未解决,4S店拒退换:可延长质保
  • 京东回应外卖系统崩溃:订单暴涨所致,已恢复
  • 来伊份发布关于消费者反映蜜枣粽问题处理的情况说明:与消费者达成和解
  • 最美西游、三星堆遗址等入选“2025十大年度IP”
  • 2024年度全国秋粮收购达3.45亿吨