【数据结构】链表带环问题分析及顺序表链表对比分析
【C语言】链表带环问题分析及顺序表链表对比分析
🔥个人主页:大白的编程日记
🔥专栏:C语言学习之路
文章目录
- 【C语言】链表带环问题分析及顺序表链表对比分析
- 前言
- 一.顺序表和链表对比
- 1.1顺序表和链表的区别
- 1.2缓存利用率(缓存命中率)
- 二.链表的带环问题
- 2.1快慢指针
- 2.2证明快慢指针相遇问题
- 2.3快指针的步长
- 2.4环的入口
- 后言
前言
哈喽,各位小伙伴大家好!由于考试周很久没有更新博客了。今天给大家带来的是链表的带环问题和顺序表链表的对比分析。话不多说,进入正题。向大厂冲锋!
一.顺序表和链表对比
1.1顺序表和链表的区别
顺序表和链表是两种不同的数据结构。他们各有各的优劣。我们就来对比分析一下他们的区别。我们这里用带头双向循环链表和顺序表做对比。
- 存储空间
顺序表:物理上是连续的。
链表:因为链表是由节点组成,每个节点由指针连接。 所以在逻辑上是连续的,但每个节点都是malloc动态开辟的,在物理空间上不一定连续。
- 随机访问
顺序表:顺序表可以通过下标来进行随机访问。
链表:链表不支持随机访问,只能从头节点开始遍历寻找节点。
- 任意位置插入删除
顺序表:如果不是尾插尾删,需要挪动数据。
链表:链表由节点组成,插入或删除只需要修改前后节点的指针指向即可。
- 扩容
顺序表:空间不够需要扩容。
扩容realloc本身会有消耗且异地扩容消耗不小,2倍扩容可能存在空间浪费。
链表:按需申请释放,需要一个申请一个,不存在扩容,不会浪费空间。
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(4);printf("%p\n", p);int* p1 = (int*)realloc(p, 40);printf("%p", p1);
}
异地扩容:
只要空间大一点,基本都是异地扩容。
原地扩容:
- 应用场景
顺序表和链表的优劣是互补的。
顺序表适合随机访问,不适合中间位置的插入删除。
链表适合任意位置的插入删除,但无法随机访问。
所以如果经常随机访问,但只需要尾插尾删就选择顺序表。
如果不经常随机访问,在中间位置插入删除就选择链表。
具体根据他们的优劣进行选择。
1.2缓存利用率(缓存命中率)
顺序表和链表的区别还有一个就是
顺序表的缓存命中率高。
链表的缓存命中率低。
为什么呢?什么是缓存命中率呢?
- 内存和硬盘
这是我们计算机的内部的存储结构。
主存也就是我们的内存和硬盘的区别就是
内存的存储空间更小,通常为8G和16G,但速度快。需要带电存储
硬盘存储空间更大,速度慢,但不需要带电存储。
他们的本质是带不带电。
例如:
如果我正在写一份ppt,因为硬盘的速度慢,所以是存在内存中的,如果我这时电脑突然没电关机。重新开机后,我的ppt就不见了。因为我没有另存到硬盘中。
只用当我们另存到硬盘中才存在。
- 寄存器和三级缓存
那既然已经有内存,内存的速度也还行,为什么还有寄存器和三级缓存呢?
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>
int main()
{int i = 0;int ret = i++;
}
以这段代码为例:
i存在内存中,也就是main函数的栈帧里。i++的执行过程是这样的:
先把i放在eax寄存器中,
对eax++,
把eax寄存器放i的内存位置
那为什么要这样做呢?
因为CPU和内存不同频,CPU跑的太快了。
如果直接访问内存数据进行++,因为内存太慢了。
他宁愿把内存中数据加载到寄存器中,CPU在寄存器执行指令,再把运行结果返回内存。
一般来说,CPU不会直接访问内存
-
寄存器
如果数据比较小(4或8字节)就会把数据加载到寄存器。 -
缓存
如果数据比较大就加载到缓存中。
缓存命中:如果要访问的数据在缓存,叫缓存命中,直接访问。
缓存不命中,如果要访问的数据不在缓存,叫缓存不命中,先把数据加载到缓存中,再访问。
- 缓存的加载
如果你要加载4个字节到缓存,通常会加载一长段空间到缓存中。而不只是4个字节。为什么呢?
把内存看作学校,缓存看作大巴,CPU看作度假村。
现在学校安排大巴把学生(数据)送到度假村去。
所以顺序表的缓存命中率高,
链表的缓存命中率低,而且会造成缓存污染。
如果大家想多了解缓存的话可以看这篇文章
与程序员相关的CPU缓存知识
二.链表的带环问题
链表带环是链表中的经典问题,值得我们深入学习。解决带环问题通常使用快慢指针相遇解决。但是你如何证明快慢指针一定相遇,以及快指针的步长不同会怎样呢?接下来,小编带大家一一探讨。
2.1快慢指针
- 题目
环形链表
- 思路
创建一个快指针和一个慢指针,快指针一次走两步,慢指针一次走一步。
如果是链表带环,快慢指针最终会相遇。不带环,则快指针走到尾。 - 代码实现
typedef struct ListNode ListNode;
bool hasCycle(struct ListNode *head)
{ListNode*slow,*fast;slow=fast=head;while(fast&&fast->next){slow=slow->next;//慢指针走一步fast=fast->next->next;//快指针走两步if(fast==slow)//快慢指针相遇{return true;}}return false;//不带环
}
2.2证明快慢指针相遇问题
那如何证明题目一定会相遇呢?
当慢指针入环时,快指针与慢指针相差N个节点。
由于快指针每次走两步,慢指针走一步。
每次移动快指针都会与慢指针的距离缩小一个节点。
当他们的距离节点缩小为0时,就会相遇。
所以快慢指针一定能够相遇。
2.3快指针的步长
那快指针是不是只能走一步呢?如果快指针走3,4,5…N步还一定能相遇吗?
- 步长为3时
证明结果如下
我们用快慢指针步长的关系列出等式,反推证明N为奇数和C为偶数的情况不会出现,从而得出结论步长为3时一定能相遇。
-
验证
-
步长为3,4,5…N
这些情况和前面的推导证明过程相似,大家有兴趣可以自己深入探究。
2.4环的入口
-
题目
环形链表二 -
思路
创建一个快指针和一个慢指针,快指针一次走两步,慢指针一次走一步。
如果是链表带环,快慢指针最终会相遇。
一个指针相遇点开始走,一个指针从头节点开始走,每次两个指针都走一步。
当两个指针相遇时,相遇节点就是入环节点。
不带环,则快指针走到尾。 -
代码实现
typedef struct ListNode ListNode ;
struct ListNode *detectCycle(struct ListNode *head)
{ListNode*slow,*fast;slow=fast=head;while(fast&&fast->next){fast=fast->next->next;slow=slow->next;if(slow==fast){ListNode* pcur=slow;while(pcur!=head){pcur=pcur->next;head=head->next;}return pcur;}}return NULL;
}
- 证明
具体证明过程如下:
- 验证
-
所以根据推导我们得出只要再相遇后,一个head指针从头节点出发,一个pcur节点从相遇点出发,等他们相遇时,相遇点就是入环点。
后言
这就是链表的带环问题和顺序表链表的对比。这些都是我们数据结构学习时的重要内容。大家一定要好好掌握。今天就分享到这里,咱们下期见!拜拜~
相关文章:

【数据结构】链表带环问题分析及顺序表链表对比分析
【C语言】链表带环问题分析及顺序表链表对比分析 🔥个人主页:大白的编程日记 🔥专栏:C语言学习之路 文章目录 【C语言】链表带环问题分析及顺序表链表对比分析前言一.顺序表和链表对比1.1顺序表和链表的区别1.2缓存利用率&#…...

快速解决找不到krpt.dll,无法继续执行代码问题
对于那些遇到计算机开机出现由于无法找到krpt.dll,进而无法继续执行代码问题的用户。 krpt.dll是计算机系统中与DirectX紧密相关的重要文件,如果它出现问题,可能会对一些特定的软件或游戏的运行产生影响。实际上,我们有多种解决该…...
C# List、LinkedList、Dictionary性能对比
数据结构性能对比 List、LinkedList、Dictionary 1. ArrayList (List:前传) ArrayList 是一个特殊数组, 通过添加和删除元素就可以动态改变数组的长度。 ArrayList集合相对于数组的优点: 支持…...

【Spring Cloud】微服务的简单搭建
文章目录 🍃前言🎄开发环境安装🌳服务拆分的原则🚩单一职责原则🚩服务自治🚩单向依赖 🍀搭建案例介绍🌴数据准备🎋工程搭建🚩构建父子工程🎈创建父…...

全球首款商用,AI为视频自动配音配乐产品上线
近日,海外推出了一款名为Resona V2A的产品,这是全球首款商用视频转音频 (V2A) 技术产品。这项突破性技术利用AI,仅凭视频数据即可自动生成高质量、与上下文相关的音频,包括声音设计、音效、拟音和环境音,为电影制作人、…...

Git管理源代码、git简介,工作区、暂存区和仓库区,git远程仓库github,创建远程仓库、配置SSH,克隆项目
学习目标 能够说出git的作用和管理源代码的特点能够如何创建git仓库并添加忽略文件能够使用add、commit、push、pull等命令实现源代码管理能够使用github远程仓库托管源代码能够说出代码冲突原因和解决办法能够说出 git 标签的作用能够使用使用git实现分支创建,合并…...

【机器学习】机器学习与时间序列分析的融合应用与性能优化新探索
文章目录 引言第一章:机器学习在时间序列分析中的应用1.1 数据预处理1.1.1 数据清洗1.1.2 数据归一化1.1.3 数据增强 1.2 模型选择1.2.1 自回归模型1.2.2 移动平均模型1.2.3 长短期记忆网络1.2.4 卷积神经网络 1.3 模型训练1.3.1 梯度下降1.3.2 随机梯度下降1.3.3 A…...

执行力不足是因为选择模糊
选择模糊:执行力不足的根源 选择模糊是指在面对多个选项时,缺乏明确的目标和方向。这种模糊感会导致犹豫不决,进而影响我们的执行力。 选择模糊的表现: 目标不明确,不知道应该做什么。优先级混乱,不清楚…...
力扣 225题 用队列实现栈 记录
题目描述 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。实现 MyStack 类: void push(int x) 将元素 x 压入栈顶。 int pop() 移除并返回栈顶元素…...
中英双语介绍意大利(Italy):有哪些著名景点、出名品牌?
中文版 意大利概述 意大利,位于欧洲南部,是一个以其悠久的历史、丰富的文化遗产和美丽的自然风光而闻名的国家。意大利不仅是文艺复兴的发源地,还拥有众多世界著名的城市、景点和品牌。 著名城市 罗马(Rome)&#x…...

Python【打包exe文件两步到位】
Python打包Exe 安装 pyinstaller(pip install pyinstaller) 执行打包命令(pyinstaller demo.py) 打完包会生成 dist 文件夹,如下如...

基于模型预测控制的PMSM系统速度环控制理论推导及仿真搭建
模型预测控制(Model Predictive Control, MPC)是一种先进的控制策略,广泛应用于工业控制中。它可以看作是一种最优控制方法,利用对象的动态模型来预测其状态的未来行为,并根据每个采样时间点特定性能目标函数的优化来确…...
【PYG】GNN和全连接层(FC)分别在不同的类中,使用反向传播联合训练,实现端到端的训练过程
文章目录 基本步骤GNN和全连接层(FC)联合训练1. 定义GNN模型类2. 定义FC模型类3. 训练循环中的联合优化解释完整代码 GNN和全连接层(FC)分别使用不同的优化器和学习率分别进行参数更新解释 基本步骤 要从GNN(图神经网…...

vue3使用方式汇总
1、引入iconfont阿里图库图标: 1.1 进入阿里图标网站: iconfont阿里:https://www.iconfont.cn/ 1.2 添加图标: 1.3 下载代码: 1.4 在vue3中配置代码: 将其代码复制到src/assets/fonts/目录下࿱…...

Turborepo简易教程
参考官网:https://turbo.build/repo/docs 开始 安装全新的项目 pnpm dlx create-turbolatest测试应用包含: 两个可部署的应用三个共享库 运行: pnpm install pnpm dev会启动两个应用web(http://localhost:3000/)、docs(http://localhost…...

初中物理知识点总结(人教版)
初中物理知识点大全 声现象知识归纳 1 .声音的发生:由物体的振动而产生。振动停止,发声也停止。 2.声音的传播:声音靠介质传播。真空不能传声。通常我们听到的声音是靠空气传来的。 3.声速:在空气中传播速度是:340…...
ChatGPT-4o大语言模型优化、本地私有化部署、从0-1搭建、智能体构建等高级进阶
目录 第一章 ChatGPT-4o使用进阶 第二章 大语言模型原理详解 第三章 大语言模型优化 第四章 开源大语言模型及本地部署 第五章 从0到1搭建第一个大语言模型 第六章 智能体(Agent)构建 第七章 大语言模型发展趋势 第八章 总结与答疑讨论 更多应用…...

【开源项目】LocalSend 局域网文件传输工具
【开源项目】LocalSend 局域网文件传输工具 一个免费、开源、跨平台的局域网传输工具 LocalSend 简介 LocalSend 是一个免费的开源跨平台的应用程序,允许用户在不需要互联网连接的情况下,通过本地网络安全地与附近设备共享文件和消息。 项目地址&…...
ARM/Linux嵌入式面经(十一):地平线嵌入式实习
地平线嵌入式实习面经 1.自我介绍 等着,在给大哥们准备了。 2.spi与iic协议可以连接多个设备吗?最多多少个?通讯时序。 这是几个问题,在回答的时候。不要一问就开口,花几秒钟沉吟思考整理一下自己的思路。 这个问题问了几个点?每个点的回答步骤。 是我的话,我会采用以…...

基于Redis的分布式锁
分布式场景下并发安全问题的引发 前面通过加锁解决了单机状态下一人一单的问题,但是当出现了分布式,前面的加锁形式不再适用 ,每个jvm有一个自己的锁监视器,只能被内部线程获取,其他jvm无法使用,那么多台j…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

DAY 47
三、通道注意力 3.1 通道注意力的定义 # 新增:通道注意力模块(SE模块) class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

转转集团旗下首家二手多品类循环仓店“超级转转”开业
6月9日,国内领先的循环经济企业转转集团旗下首家二手多品类循环仓店“超级转转”正式开业。 转转集团创始人兼CEO黄炜、转转循环时尚发起人朱珠、转转集团COO兼红布林CEO胡伟琨、王府井集团副总裁祝捷等出席了开业剪彩仪式。 据「TMT星球」了解,“超级…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...

使用LangGraph和LangSmith构建多智能体人工智能系统
现在,通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战,比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...

Proxmox Mail Gateway安装指南:从零开始配置高效邮件过滤系统
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:「storms…...
Leetcode33( 搜索旋转排序数组)
题目表述 整数数组 nums 按升序排列,数组中的值 互不相同 。 在传递给函数之前,nums 在预先未知的某个下标 k(0 < k < nums.length)上进行了 旋转,使数组变为 [nums[k], nums[k1], …, nums[n-1], nums[0], nu…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...