链表(基础详解、实现、OJ笔试题)
文章目录
- 🧚什么是链表(链表概念及分类)
- 链表分类
- 单链表和双链表的区别
- 🚴♂️单链表、双向链表的实现
- 单链表的实现
- 双向链表的实现
- 🍉链表经典OJ笔试题
- 反转单链表
- 移除链表元素
- 合并两个有序链表
- 链表分割
- 链表的中间结点
- 环形链表
- 环形链表 I:判断链表中是否有环
- 环形链表 II:判断链表开始入环的第一个结点
- 复制带随机指针的链表
- 🥬链表相关文章直通车
大家好,我是纪宁。
这篇文章将带来完整版的链表内容的讲解。文章内容包括链表的概念、分类、单双链表的实现、链表的经典OJ题目等。每一个专题中讲解了相应问题实现思路及方法,当然,实际解决过程中肯定也会出现各种各样的小问题,记录每个问题具体实现方法和代码的文章链表在每个专题的末尾,点击即可进入。其次,文章末尾也提供了上述所有问题链接的合集,供大家前往参考学习。
🧚什么是链表(链表概念及分类)
链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。非连续的意思就是链表的每一部分可以在内存的任意一块区域存在,且这块区域的地址是随机的,所以一般用动态内存来开辟这块空间的地址。而链表的每一部分都称为一个节点,每个节点分为两部分:数据域和指针域,通过指针域即可访问其他结点的数据。
链表分类
无头单向非循环链表:结构简单,一般不会单独用来存数据。实际中更多是作为其他数据结构的子结构,如哈希桶、图的邻接表等等。另外这种结构在笔试面试中出现很多。

单链表的每个节点分为两部分,一部分存储数据,一部分存储下一个节点的地址。前一个节点中存储着下一个节点的地址,这也是单链表能连起来的原因。
带头双向循环链表:结构最复杂,但结构最优,一般用在单独存储数据。实际中使用的链表数据结构,都是带头双向循环链表。

双向链表的节点有两个指针域和一个数据域,两个指针一个指向后一个节点,另一个指向前一个节点,数据域中存储数据。默认双向链表都是有带哨兵位的头节点,哨兵位的头节点中储存着第一个有效节点的地址(phead->next)和最后一个有效节点的地址(phead->prev)。 除了上面两个最常用的链表之外,还有无头单向循环链表、带头单向循环链表、带头单向不循环链表、无头双向循环链表等等,总之可以将是否带头、是否循环、单双向这三个条件排列组合,另外还会有一些另类的复杂列表,文末会举出例子。
单链表和双链表的区别
单链表的指针域中只有一个地址,指向的是下一个结点的地址。而双链表的指针域中有两个地址:前一个结点的地址和后一个结点的地址。
单链表找尾结点比较麻烦,需要遍历;而双链表找尾结点只需要找头结点的上一个结点即可。
单链表只要一直往后遍历就会遇到空指针结束,而双向链表则可能会难以控制循环结束的条件而死循环下去。
单链表中一般默认没有哨兵位的头结点;而双链表中默认头结点,里面存的是最后一个结点和第一个有效结点的地址。
逻辑图对比

物理图对比

🚴♂️单链表、双向链表的实现
将链表中的数据类型重定义为某种类型,并定义一个链表节点的结构体,其中节点的数据域是当前节点的数据,另一部分则是地址。即将链表的数据域和指针域放在一个结构体中,且链表中存储的数据最好是可变的,每生成一个链表都要单独开辟额外的空间。
单链表的实现
每开辟一个结点的空间,都要为这个结点的数据域赋值,并让它的指针域指向NULL。单链表的头插头删都要传二级指针,因为要改变头插头删都要改变头指针的指向,删除某一结点,需要先找到这个结点的上一个结点,必要时候要用另一个结点保存某个结点的地址,防止地址丢失的情况。
具体实现方式:单链表的实现
双向链表的实现
双向链表在开辟结点时,要先将结点的指针域置空,当确定结点位置时,再将结点的两个指针域指向应指向的结点。
具体实现方式:双链表的实现
🍉链表经典OJ笔试题
反转单链表

思路是用三个指针,从前到后一次改变每个结点的指向。
题目及详解:反转单链表
移除链表元素

定义两个指针,保证从第二个结点开始,一个指针在另一个指针的后面,这样就能在不丢失数据的情况下移除链表某结点。
题目及详解:移除链表元素
合并两个有序链表

将两个链表的节点逐个比较,小的尾插到新链表的后面,每次尾插完,新链表和较小值的链表的指针都要向前走,有一个为空就停止循环,最后再将那个不为空的链表节点全部尾插到新链表。

这道题最好的思路是构建一个哨兵位来实现尾插,不构建哨兵位也可以,但需要考虑更多的边界条件。
题目及详解:合并两个有序链表
链表分割
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
如图,给定的链表为 4-5-3-1-2-7 ,给一定值为 3,分割后的值为 1-2-4-5-3-7

此题最好的解决方法是开辟两个哨兵位的头结点,将这两两部分的数据按要求一次尾插到两个哨兵位的后面,再将较小的一部分的尾结点指向较大部分的第一个结点,将较大部分的最后一个结点置空,最后将两个哨兵位释放,返回较小部分的第一个结点的地址即可。
题目及详解:链表分割
链表的中间结点
给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
此题知识点:快慢指针
控制两个指针,快指针每次向前走两步步,慢指针每次向前走一步,当快指针走到尾部的时候,慢指针则刚好走到中间结点。
题目及详解:链表的中间结点
环形链表
环形链表中用到了快慢指针和追及问题相关知识带点。
环形链表 I:判断链表中是否有环
环形链表 II:判断链表开始入环的第一个结点
环形链表I、II 题目及详解:环形链表
复制带随机指针的链表
给你一个长度为 n 的链表,每个节点包含一个额外增加的随机指针 random ,该指针可以指向链表中的任何节点或空节点。构造这个链表的 深拷贝。 深拷贝应该正好由 n 个 全新 节点组成,其中每个新节点的值都设为其对应的原节点的值。新节点的 next 指针和 random 指针也都应指向复制链表中的新节点,并使原链表和复制链表中的这些指针能够表示相同的链表状态。复制链表中的指针都不应指向原链表中的节点。

复制后的链表相关位置的索引必须和原链表一模一样。
题目思路
- 拷贝所有节点,,每个结点放在对应原节点的后面。
- 将每个 random 指向对应的位置。
- 将复制的链表解下来,尾插到一起,并将原链表恢复。
题目及详解:复制带随机指针的链表
🥬链表相关文章直通车
单链表的实现
双链表的实现
反转单链表
移除链表元素
合并两个有序链表
链表分割
链表的中间结点
环形链表
复制带随机指针的链表
相关文章:
链表(基础详解、实现、OJ笔试题)
文章目录 🧚什么是链表(链表概念及分类)链表分类单链表和双链表的区别 🚴♂️单链表、双向链表的实现单链表的实现双向链表的实现 🍉链表经典OJ笔试题反转单链表移除链表元素合并两个有序链表链表分割链表的中间结点…...
W5100S-EVB-PICO作为TCP Client 进行数据回环测试(五)
前言 上一章我们用W5100S-EVB-PICO开发板通过DNS解析www.baidu.com(百度域名)成功得到其IP地址,那么本章我们将用我们的开发板作为客户端去连接服务器,并做数据回环测试:收到服务器发送的数据,并回传给服务…...
大数据-玩转数据-Redis 安装与使用
一、说明 大多数企业都是基于Linux服务器来部署项目,而且Redis官方也没有提供Windows版本的安装包。因此课程中我们会基于Linux系统来安装Redis. 此处选择的Linux版本为CentOS 7. Redis的官方网站地址:http://download.redis.io/releases 二、下载 m…...
实时指标-1日留存率
2个DWD层 登录→kafka注册→kafka1个DWS 弄2条流,从kafka读取数据将昨日注册数据存到状态中,TTL为2天,存到map状态中,key为注册日期,value为set,存储注册的uid将登录流和注册流进行连接来一条登录数据&…...
【玩转23种Java设计模式】行为型模式篇:责任链模式
软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 汇总目录链接&…...
【C#】获取电脑CPU、内存、屏幕、磁盘等信息
通过WMI类来获取电脑各种信息,参考文章:WMI_04_常见的WMI类的属性_wmi scsilogicalunit_fantongl的博客-CSDN博客 自己整理了获取电脑CPU、内存、屏幕、磁盘等信息的代码 #region 系统信息/// <summary>/// 电脑信息/// </summary>public p…...
途乐证券-最准确的KDJ改良指标?
KDJ目标是技术剖析的一种重要目标之一,它是利用随机目标(%R)发展而来的,是一种反映商场超买和超卖状况的买卖目标。KDJ目标由快线(K线)、慢线(D线)和随机值(J线ÿ…...
数据结构——线性表
文章目录 线性表的定义和基本操作顺序表线性表的链式表示 线性表的定义和基本操作 线性表是具有相同数据类型的(n≥0)个数据元素的有限序列,其中n为表长,当n0时线性表是一个空表。若用L命名线性表,则其中一般表示为:L(a1,a2,a3, …...
SpringBoot系列之基于Jersey实现文件上传API
前言 JAX-RS:JAX-RS是可以用可以用于实现RESTFul应用程序的JAVA API,给开发者提供了一系列的RESTFul注解Jersey:是基于JAX-RX API的实现框架,用于实现RESTful Web 服务的开源框架。 JAX-RX常用的注解: javax.ws.rs.Pa…...
【LangChain】Prompts之示例选择器
LangChain学习文档 【LangChain】向量存储(Vector stores)【LangChain】向量存储之FAISS【LangChain】Prompts之Prompt templates【LangChain】Prompts之自定义提示模板【LangChain】Prompts之示例选择器 概要 如果您有大量示例,您可能需要选择要包含在提示中的哪…...
Neo4j之CREATE基础
在 Neo4j 中,CREATE 语句用于创建节点、关系以及节点属性。 创建节点: CREATE (p:Person {name: John, age: 30});这个查询会创建一个具有 "Person" 标签的节点,节点属性包括 "name" 和 "age"。 创建带有关…...
Kali Hyper-V安装正常启动后 黑屏 只能进命令模式
问题: Hyper-V安装虚拟机Kali系统一切安装正常, 没有出现错误. 安装成功后重启,只能进入命令模式,tt1-tt6,进不去GUI桌面. 尝试: 一代二代虚拟硬盘都试过,同样问题,只能开进后进入命令模式,在命令模式下一切运行正常, 也修复过系统 GNOM等的,不管用. 以下为国外论坛给的建议,尝…...
【人工智能124种任务大集合】-集齐了自然语言处理(NLP),计算机视觉(CV),语音识别,多模态等任务
大家好,我是微学AI,今天给大家介绍一下人工智能124种任务大集合,任务集合主要包括4大类:自然语言处理(NLP)、计算机视觉(CV)、语音识别、多模态任务。 我这里整理了124种应用场景任…...
IntelliJ IDEA快捷键大全
文章目录 1、构建/编译2、文本编辑3、光标操作4、文本选择5、代码折叠6、辅助编码7、上下文导航8、查找操作9、符号导航10、代码分析11、运行和调试12、代码重构13、全局 CVS 操作14、差异查看器15、工具窗口 本文参考了 IntelliJ IDEA 的官网,列举了IntelliJ IDEA&…...
阿里云轻量应用服务器_2核4G4M_2核2G3M_性能测评
阿里云轻量应用服务器2核2G3M带宽108元一年,系统盘为50GB高效云盘;轻量服务器2核4G4M带宽,60GB高效云盘297.98元12个月。目前轻量应用服务器只有2核2G和2核4G有活动,阿里云百科分享阿里云轻量应用服务器入口: 目录 阿…...
猿人学刷题系列(第一届比赛)——第二题( js 混淆 - 动态cookie 1)
题目:提取全部5页发布日热度的值,计算所有值的加和 地址:https://match.yuanrenxue.cn/match/2 思路分析 本题我们会简单说一下两种不同的方式去处理,一种是不还原混淆代码直接从源代码硬扣生成逻辑,另一种则是还原…...
ubuntu网络管理
主机-ip,service—port 分别查看/etc/hosts,/etc/host.conf;/etc/services,/etc/resolv.conf; 内核更新——linux-image-generic 6.2.0-24.24 非常抱歉,我误解了你的问题。如果你想更新已安装的内核版本…...
您可能并不需要单页应用程序
前端框架的迅速崛起,如React、Angel、Vue.js、Elm等,使得单页面应用程序(Single Page Application)在网络上无处不在。对于许多开发人员来说,这些已经成为他们“默认”工具集的一部分。当他们开始一个新项目时…...
基于低代码和数字孪生技术的电力运维平台设计
电力能源服务商在为用能企业提供线上服务的时候,不可避免要面对用能企业的各种个性化需求。如果这些需求和想法都要靠平台厂家研发人员来实现,那在周期、成本、效果上都将是无法满足服务运营需要的,这也是目前很多线上能源云平台应用效果不理…...
【Github】SourceTree技巧汇总
sourceTree登录github账户 会跳转到浏览器端 按照Git Flow 初始化仓库分支 克隆远程仓库到本地 推送变更到远程仓库 合并分支 可以看到目前的本地分支(main、iOS_JS)和远程分支(origin/main、origin/HEAD、origin/iOS_JS)目前所处…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
基于 TAPD 进行项目管理
起因 自己写了个小工具,仓库用的Github。之前在用markdown进行需求管理,现在随着功能的增加,感觉有点难以管理了,所以用TAPD这个工具进行需求、Bug管理。 操作流程 注册 TAPD,需要提供一个企业名新建一个项目&#…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...
pgsql:还原数据库后出现重复序列导致“more than one owned sequence found“报错问题的解决
问题: pgsql数据库通过备份数据库文件进行还原时,如果表中有自增序列,还原后可能会出现重复的序列,此时若向表中插入新行时会出现“more than one owned sequence found”的报错提示。 点击菜单“其它”-》“序列”,…...
