问题:如何判断单链表是否有环?如何找到环的起始点?如何知道环的长度。
方法:使用快慢指针法,即快指针每次移动两个节点,慢指针每次移动一个节点
(1)判断是否有环
如图所示,假设有两个节点fast,slow分别指向链表头,即图中的节点1所在的地址。然后令
然后循环执行知道slow等于fast时,即可推断出环的存在。注意循环条件为fast != NULL && fast->next != NULL。slow = slow->next; fast = fast->next->next;代码如下所示:
#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node * next; }Node; Node * get_circle_link(int length, int local) { Node *temp = NULL; Node *phead = NULL; Node *tail = NULL; int i; //创建单链表 for (i = 0; i < length; i++) { temp = (Node *)malloc(sizeof(Node)); temp->next = NULL; temp->data = length - i; if (phead == NULL) { tail = temp; } temp->next = phead; phead = temp; } //形成环 for (temp = phead, i =1; i < local; i++) { temp = temp->next; } tail->next = temp; return phead; } void link_print(Node *temp) { while (temp != NULL) { printf("%p:%d\t",temp,temp->data); temp = temp->next; getchar(); } } //利用快慢指针判断链表是否有环 int get_circle_local(Node *phead) { Node * fast = phead; Node * slow = phead; while (fast != NULL && fast->next != NULL) { fast = fast->next->next; //fast一次跳两个节点 slow = slow->next; //slow一次跳一个节点 if (fast == slow) { return 1; } } return 0; } int main() { Node * phead = NULL; int local = 0; int number = 0; scanf("%d",&number); //链表的节点数 scanf("%d",&local); //链表环的节点数 if (number < local || local <= 0 || number <= 0) { printf("number MUST >= local, and MUST be positive integer\n"); exit(EXIT_FAILURE); } phead = get_circle_link(number,local); //link_print(phead); int ret = 0; if (get_circle_local(phead) == 1) { printf("has circle\n"); } else printf("no circle\n"); return 0; }
输入:6 3
运行结果:
(2) 寻找环的起始点
假设节点1到节点3距离为L,而节点3到节点5的距离为A,则有L + A = (L + A + N*X)/2,其中N为快捷点与慢节点相遇时走过的多少个环,X为1个环的环数。
因此,当判断fast=slow时,将slow和fast节点的步长都改为1步,即
slow = slow->next; fast = fast->next;当slow再次等于fast时,相遇的节点即为起始点
程序为:
输入:6 4#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node * next; }Node; Node * get_circle_link(int length, int local) { Node *temp = NULL; Node *phead = NULL; Node *tail = NULL; int i; //创建单链表 for (i = 0; i < length; i++) { temp = (Node *)malloc(sizeof(Node)); temp->next = NULL; temp->data = length - i; if (phead == NULL) { tail = temp; } temp->next = phead; phead = temp; } for (temp = phead, i =1; i < local; i++) { temp = temp->next; } tail->next = temp; return phead; } void link_print(Node *temp) { while (temp != NULL) { printf("%p:%d\t",temp,temp->data); temp = temp->next; getchar(); } } //利用快慢指针判断链表是否有环 int get_circle_local(Node *phead) { Node * fast = phead; Node * slow = phead; while (fast != NULL && fast->next != NULL) { fast = fast->next->next; //fast一次跳两个节点 slow = slow->next; //slow一次跳一个节点 if (fast == slow) { //return 1; for (slow = phead; slow != fast;) { slow = slow->next; fast = fast->next; } return slow->data; } } return 0; } int main() { Node * phead = NULL; int local = 0; int number = 0; scanf("%d",&number); //链表的节点数 scanf("%d",&local); //链表环的节点数 if (number < local || local <= 0 || number <= 0) { printf("number MUST >= local, and MUST be positive integer\n"); exit(EXIT_FAILURE); } phead = get_circle_link(number,local); //link_print(phead); int ret = 0; if ((ret = get_circle_local(phead)) > 0) { printf("has circle,local is %d\n",ret); } else printf("no circle\n"); return 0; }结果为:
(3)判断环的长度
当判断链表有环(slow==fast)时,设置fast的步长为2,slow的步长为1,即
slow = slow->next; fast = fast->next->next;当下次再次相遇时,两者的走过的距离差即为环的长度。
<span style="font-size:18px;">程序如下:</span><pre name="code" class="cpp">#include <stdio.h> #include <stdlib.h> typedef struct node { int data; struct node * next; }Node; Node * get_circle_link(int length, int local) { Node *temp = NULL; Node *phead = NULL; Node *tail = NULL; int i; //创建单链表 for (i = 0; i < length; i++) { temp = (Node *)malloc(sizeof(Node)); temp->next = NULL; temp->data = length - i; if (phead == NULL) { tail = temp; } temp->next = phead; phead = temp; } for (temp = phead, i =1; i < local; i++) { temp = temp->next; } tail->next = temp; return phead; } void link_print(Node *temp) { while (temp != NULL) { printf("%p:%d\t",temp,temp->data); temp = temp->next; getchar(); } } //利用快慢指针判断链表是否有环 int get_circle_local(Node *phead) { Node * fast = phead; Node * slow = phead; int temp = 0; while (fast != NULL && fast->next != NULL) { fast = fast->next->next; //fast一次跳两个节点 slow = slow->next; //slow一次跳一个节点 if (fast == slow) { while (fast != NULL && fast->next != NULL) { fast = fast->next->next; slow = slow->next; temp++; if (fast == slow) { return temp; } } } } return 0; } int main() { Node * phead = NULL; int local = 0; int number = 0; scanf("%d",&number); //链表的节点数 scanf("%d",&local); //链表环的节点数 if (number < local || local <= 0 || number <= 0) { printf("number MUST >= local, and MUST be positive integer\n"); exit(EXIT_FAILURE); } phead = get_circle_link(number,local); //link_print(phead); int ret = 0; if ((ret = get_circle_local(phead)) > 0) { printf("has circle,local is %d\n",ret); } else printf("no circle\n"); return 0; }
输入:6 4运行结果为:<img src="https://img-blog.youkuaiyun.com/20140913223547183" alt="" />
相关推荐
WorkBuddy 集成 飞书CLI,全程10分钟,丝滑无比,老板要注意了...
飞书CLI实测:10分钟实现AI操控飞书办公 飞书CLI作为命令行工具,让用户通过简单命令完成飞书各项操作。本文记录了从安装到使用的完整过程:一键安装仅需10分钟,支持200多条命令覆盖飞书全部功能,与AI结合后可实现自然语言办公。实测中成功用语音指令创建了7天发文计划日程,验证了其便捷性。虽然首次认证存在超时问题,但整体体验流畅。该工具将复杂操作简化为自然语言指令,大幅提升办公效率,特别适合需要频繁使用飞书的用户。后续还将探索更多自动化办公场景。
数据结构-链表带环问题
C语言 刷题 数据结构 链表带环 入口节点
三极管自激升压电路设计 - 从参数计算到实践验证
本文详细解析了三极管自激升压电路(焦耳小偷电路)的设计原理与实践方法。通过剖析自激振荡机制与三极管电流关系,指导读者完成从核心参数计算、关键元件选型到面包板搭建调试的全过程。文章重点阐述了如何利用电感、三极管等基础元件实现低压直流到高压的转换,是理解开关电源与电磁能量转换的绝佳实践项目。
链表带环问题(详解)
链表带环问题,带随机指针链表复制问题。
小程序选项卡以及swiper套用(跨页面)
选项卡tab和swpier之间的套用 其实我之前写过一篇选项卡的切换demo,大家阔以参考一下 小程序多个选项卡切换 那今天写这个demo呢,是因为项目需求,所以仅供参考。 我是拿到了home.wxml的数组下标, 通过url传参的方式去将这个id传到下一个页面, 下一个页面接收以后再将id赋值给对应的tabI或者currentId(swiper 的下标) 实现上一个页面进来以后直接进入对应的页...
基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的商品识别系统(深度学习+UI界面+训练数据集+Python代码)
随着新零售和智能仓储的快速发展,商品识别技术成为计算机视觉领域的重要研究方向。本文详细介绍了基于YOLO系列算法的商品识别系统的完整实现方案,涵盖算法原理、数据集构建、模型训练、系统集成和可视化界面开发。通过对比YOLOv5到YOLOv8各版本性能差异,我们构建了一个高效、准确且用户友好的商品识别系统,并提供完整的代码实现。
一网打尽带环链表问题(手把着手带你理解,木有基础也能看懂!)
带环链表问题是一个非常经典的OJ题,本文将手把手,类比现实中操场跑步的生动例子,来解决如何判断一个链表是带环还是不带环链表,然后利用数学推导的方法,求出带环链表入环节点的位置,同时也介绍了暴力拆解带环链表的方法求入环节点的方法,内容十分劲爆。最后我们引入番外,探索不同的速度差下,在环内fast和slow能否一定相遇
在STM32F103RBT6微控制器上利用USB虚拟Com端口技术,高效实现ADC数据传输:详细操作步骤与示例代码解析
以上就是在STM32F103RBT6上使用USB虚拟Com端口实现ADC数据传输的全部内容。虽然过程中有很多步骤和细节需要注意,但只要按照步骤来,理解每一段代码的作用,就完全可以掌握这个过程。在实际应用中,我们可能需要根据实际需要修改一些代码,如调整ADC的参数,改变数据的处理方式等。但是,只要理解了这个过程,我们就可以很灵活地进行修改。希望这篇文章对你有所帮助。如果你有任何疑问,欢迎在评论区留言,我会尽我所能进行解答。
详解链表带环的问题
在我们练习链表的习题的时候,不可避免的会遇到链表带环的问题,或许你知道用快慢指针来解决带环链表的问题,但你不一定知道其中蕴含的数学属性。
【YOLO11改进 - 特征融合】利用Hyper-YOLO 的混合聚合网络(MANet)改进yolo11,提升基础网络的特征提取能力
【YOLO11改进 - 特征融合】利用Hyper-YOLO 的混合聚合网络(MANet)改进yolo11,提升基础网络的特征提取能力
目标检测YOLO实战应用案例100讲-基于YOLOv7的番茄采摘机械手场景感知及试验(下)
根据软件系统的设计需求,制定系统的可行性方案分析,编写系统的相关程序和 调试运行环境,对系统进行测试,以实现对番茄数据的采集及监测。登陆界面登陆后,进入选择界面,菜单包括了对番茄种植棚室的固定相机数据的监测、 对番茄采摘机械手的双目相机采集的番茄的静态、动态数据的获取、对番茄静态、动态数 据处理的功能菜单等选项。与利用人工去进行对于番茄果实的识别和数目的统计相比,番茄视觉系统自动记录番 茄数量以及红色已经成熟的番茄、青色未成熟番茄的数量,减轻人工记录的工作量,减少 人工记录的误差,从经济方面是可行的。
数据结构——链表的带环问题
所以其中的距离,假如N为偶数,那么距离变化为N,N-2,N-4......4,2,0;如果N为奇数,那么距离变化为N,N-2,N-4......3,1,-1。假设slow和fast两个指针在如图所在的位置,并设其之间的距离为N,进行追击距离会从N,N-1,N-2......3,2,1,0,逐渐减小为0,最后相遇。如果错过,距离为-1,则开始新一轮的追击,设环形周长为C,所以距离变成了C-1。N%3==0,N%3==1,N%3==2,分别是三种状况。例如,slow走1步,fast走4步,速度差是3。
PyTorch深度学习实战(3)——使用PyTorch构建神经网络
PyTorch 是一个用于构建深度神经网络的库,具有灵活性和可扩展性,可以轻松自定义模型。在本节中,我们将使用 PyTorch 库构建神经网络,利用张量对象操作和梯度值计算更新网络权重,并利用 Sequential 类简化网络构建过程,最后还介绍了如何使用 save、load 方法保存和加载模型,以节省模型训练时间。
链表环问题
在实际应用中,快慢指针法(Floyd的循环查找算法)因其高效且不需要额外空间(除了指针变量)而被广泛使用。哈希表法虽然时间复杂度也是O(n),但需要额外的存储空间。双重遍历法的时间复杂度较高,为O(n^2),因此在链表较长时效率较低。标记法则可能不适用于需要保持链表结构不变的场景。
迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)
迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)
STM32F407中文手册
STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。
判断单链表是否有环并找到环的入口等问题
判断单链表是否有环并找到环的入口等问题 假设一个单链表有环,他就是下面的这种情况: 我们有下面几个问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 对于这些问题有一种方法就是...
华为的C语言编程规范.pdf
华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。
链表有环问题
链表有环问题
老版QQ原生表情gif动态
这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。
【链表1】有关链表环的各种问题
==小记== 以前只研究过如何判断一个链表是否有环,结果百度三面的时候SB了,因为关链表环有各种各样的问题 【问题1】如何判断一个链表是否有环 【问题2】如何选择两个指针的步长 【问题3】链表环的起点在哪
链表:链表环问题总结
之前写了篇关于链表的博客,突然想起以前遇到的一些关于链表环问题的情况。所以赶紧百度了一下,现在作一下整理。给定一个单链表,只给出头指针h:1、如何判断是否存在环?2、如何知道环的长度?3、如何找出环的连接点在哪里?4、带环链表的长度是多少?1、如何判断是否存在环?对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fa...
有关链表环的问题
链表的环的问题一般分为三个阶段:判断是否有环,环的长度,环的起点。 1.判断是否有环:利用快慢指针。 两个指针从同一个起点出发,一个走两步,一个走一步。当两个指针相遇时,则证明有环。这个组合应该是最快的了。当提升1倍的速度,必须考虑路程的增加必须少于环长的一半,否则是没有效果的。当环比较大的时候,这是不合适的。 int linkedListCycleLength(ListNode *head
单链表有环的几个问题
转自:https://www.cnblogs.com/dancingrain/p/3405197.html 给定一个单链表,判断其中是否有环,已经是一个比较老同时也是比较经典的问题,在网上搜集了一些资料, 然后总结一下大概可以涉及到的问题,以及相应的解法。 首先,关于单链表中的环,一般涉及到一下问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 5.如果存在环,求出环上距离任意一个.
单向链表环相关问题
目录 一、判断单链表中是否有环 二、求有环单链表的环长 三、求有环单链表的环起点 四、求有环单链表的链表长度 五、代码实现 六、确定两个单向链表是否相交 核心:快慢指针(fast每次2步、slow每次1步) 参考 -1- - 2- 一、判断单链表中是否有环 使用两个指针从头开始扫描链表。 如果存在环,则两指针会相遇;如果不存在环指针fast遇到NUL...
从数学原理剖析链表中的环问题
找题目太麻烦了,为了偷懒,本文中部分前面7个题目引用自以下文章,不过描述方式并不是照抄,是根据自己的理解从数学原理层面进行了说明: https://www.cnblogs.com/yorkyang/p/10876604.html 很多同学在面试时,都遇到过链表中的环问题,本文对于链表环的常见问题给出解答,并对原因进行透彻的分析。 先列一下常见的问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 5.如
链表有环的问题
给定一个单链表,判断其中是否有环,已经是一个比较老同时也是比较经典的问题,在网上搜集了一些资料, 然后总结一下大概可以涉及到的问题,以及相应的解法。 首先,关于单链表中的环,一般涉及到一下问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 5.如果存在环,求出环上...
【链表问题】单向链表判断是否有环、求入环节点、求环长、求链表长度
目录 题目: 思路: 代码实现 注意点 此题的其他变式 题目 判断一个单项链表是否有环,如果有环,返回入环节点的值,如果无环,返回-1.要求空间复杂度为O(1). 思路 空间复杂度如果没有要求, 可以用哈希表来判断。 在空间复杂度为O(1)的情况下,环状链表相关问题通常用快慢指针来辅助完成。 快指针从头节点开始一次走两步,慢指针从头节点开始一次走一步。如果快指针为空或者...
1142



被折叠的 条评论
为什么被折叠?



