检测链表中是否存在环

题目、解析和代码

题目:给定一个单链表,判断其中是否有环的存在
解析:这里使用两个遍历速度不一样的结点进行判断,一个慢结点从首结点开始遍历,这个结点每次只遍历一个结点;一个快结点从第二个结点进行遍历,一次遍历两个结点。
若是链表中存在环,那么必然在某个结点处相遇;若是没有环,那么尾结点后继指针指向空。
LinkedListChainTest.c代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef struct operatorNodeStruce {int data;struct operatorNodeStruce* next;
}operatorNode;int main(int argc, char *argv[]) {if(argc == 1){printf("请输入链表中结点个数和环的接连位置\n");return 0;}else if(argc == 2){printf("请输入环的接连位置,负数表示没有环\n");return 0;}else if(argc > 3){printf("参数不能大于3个\n");return 0;}int nodeNumber = atoi(argv[1]);int chainNodeIndex = atoi(argv[2]);if(chainNodeIndex>nodeNumber){printf("环的接连位置应该小于链表中结点个数\n");return 0;}operatorNode *head = NULL;operatorNode *storeNode = NULL;int i=1;// 创建链表,这个链表有nodeNumber个结点for(;i<=nodeNumber;i++){operatorNode *newNode = (operatorNode *)malloc(sizeof(operatorNode));newNode->next = NULL;newNode->data = i;if(head == NULL){head = newNode;storeNode = head;}else{storeNode->next = newNode;}if(storeNode -> next != NULL){storeNode = storeNode -> next;}}//把最后一个结点的后继指针next指向第chainNodeIndex个结点,这样的话才能形成环operatorNode *chainNodeBefore = NULL;operatorNode *node= NULL;if(chainNodeIndex > 0){for(int i=0;i<chainNodeIndex;i++){if(node == NULL){node = head;}chainNodeBefore = node;node = node->next;}}storeNode->next = chainNodeBefore;// 使用快慢结点法来判断是否有环,slowNode从第一个结点开始往后遍历,每次只遍历一个结点;fastNode从第二个结点开始往后遍历,每次遍历二个结点;// 要是有环,快结点(fastNode)一定能够在某个结点处跟慢结点(slowNode)相遇operatorNode *fastNode = NULL;if(head->next != NULL){fastNode = head->next;}operatorNode *slowNode = head;while(true){if(fastNode== NULL){printf("无环\n");return 0;}else if(fastNode->next == NULL){printf("无环\n");return 0;}else if(fastNode->next->next == NULL){printf("无环\n");return 0;}else{if(slowNode == fastNode){printf("有环\n");return 0;}slowNode = slowNode->next;fastNode = fastNode->next->next;}}return 0;
}

gcc LinkedListChainTest.c -o LinkedListChainTest进行编译。
在这里插入图片描述

./LinkedListChainTest 6 4表示这个链表有6个结点,最后一个结点后继指针指向第4个结点,就像下图所示。
在这里插入图片描述

./LinkedListChainTest 7 2表示这个链表有7个结点,最后一个结点后继指针指向第2个结点,就像下图所示。
在这里插入图片描述

./LinkedListChainTest 8 3表示这个链表有8个结点,最后一个结点后继指针指向第3个结点,就像下图所示。
在这里插入图片描述

遍历解析

./LinkedListChainTest 6 4为例进行解析。
在这里插入图片描述
如上图,蓝色圆心虚线箭头为慢结点(slowNode)所在位置的标识。

在这里插入图片描述
如上图,绿色实心箭头为快结点(fastNode)所在位置的标识。

刚开始的实例图如下:
在这里插入图片描述

1次遍历之后,慢结点在第2个结点处,快结点在第4个结点处:
在这里插入图片描述

2次遍历之后,慢结点在第3个结点处,快结点在第6个结点处:
在这里插入图片描述

3次遍历之后,慢结点在第4个结点处,快结点在第5个结点处:
在这里插入图片描述

4次遍历之后,慢结点在第5个结点处,快结点在第5个结点处,可以判定有环:
在这里插入图片描述

复杂度分析

结点个数环的接连位置快结点在环中所落位置遍历次数
612、4、65
623、5、2、4、64
634、63
645、4、65
6565
6665
711、3、5、7、2、4、66
722、4、65
733、5、7、4、64
744、63
755、7、65
7665
7766

若链表中有2n(n>=1,是正整数,2n为偶数)个结点:

那么若环的连接位置x不大于n,那么遍历次数为2n-x
若是环的连接位置x大于n,则最多遍历次数小于等于2n-1,还没有总结出来公式。

若链表中有2n+1(n>=1,是正整数,2n+1为偶数)个结点:

那么环的连接位置x若不大于n+1,那么遍历次数为2n+1-x
若是环的连接位置x大于n,则最多遍历次数小于等于2n+1,还没有总结出来公式。

若是没有环的话,最多遍历次数是n/2
综上所述,最好时间复杂度和最坏时间复杂度都是O(n),平均时间复杂度也是O(n)
而空间复杂度是O(1),因为除了存储变量的必要空间,没有申请额外的空间。
因为需要更好地分析时间复杂度,所以,我把代码修改成下方所示:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>typedef struct operatorNodeStruce {int data;struct operatorNodeStruce* next;
}operatorNode;int main(int argc, char *argv[]) {if(argc == 1){printf("请输入链表中结点个数和环的接连位置\n");return 0;}else if(argc == 2){printf("请输入环的接连位置,负数表示没有环\n");return 0;}else if(argc > 3){printf("参数不能大于3个\n");return 0;}int nodeNumber = atoi(argv[1]);int chainNodeIndex = atoi(argv[2]);if(chainNodeIndex>nodeNumber){printf("环的接连位置应该小于链表中结点个数\n");return 0;}operatorNode *head = NULL;operatorNode *storeNode = NULL;int i=1;// 创建链表,这个链表有nodeNumber个结点for(;i<=nodeNumber;i++){operatorNode *newNode = (operatorNode *)malloc(sizeof(operatorNode));newNode->next = NULL;newNode->data = i;if(head == NULL){head = newNode;storeNode = head;}else{storeNode->next = newNode;}if(storeNode -> next != NULL){storeNode = storeNode -> next;}}//把最后一个结点的后继指针next指向第chainNodeIndex个结点,这样的话才能形成环operatorNode *chainNodeBefore = NULL;operatorNode *node= NULL;if(chainNodeIndex > 0){for(int i=0;i<chainNodeIndex;i++){if(node == NULL){node = head;}chainNodeBefore = node;node = node->next;}}storeNode->next = chainNodeBefore;// 使用快慢结点法来判断是否有环,slowNode从第一个结点开始往后遍历,每次只遍历一个结点;fastNode从第二个结点开始往后遍历,每次遍历二个结点;// 要是有环,快结点(fastNode)一定能够在某个结点处跟慢结点(slowNode)相遇operatorNode *fastNode = NULL;if(head->next != NULL){fastNode = head->next;}operatorNode *slowNode = head;int chainNodetimes = 0;while(true){if(chainNodetimes != 0){printf("fastNode data:%d\tslowNode data: %d\n",fastNode->data,slowNode->data);}if(fastNode== NULL){printf("无环\n");return 0;}else if(fastNode->next == NULL){printf("无环\n");return 0;}else if(fastNode->next->next == NULL){printf("无环\n");return 0;}else{if(slowNode == fastNode){printf("循环次数:%d\n",chainNodetimes);printf("有环\n");return 0;}slowNode = slowNode->next;fastNode = fastNode->next->next;chainNodetimes++;}}return 0;
}

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

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

相关文章

交通科技与管理杂志社交通科技与管理编辑部2023年第9期目录

专家论坛 黑龙江省经济高质量发展与生态环境保护耦合协调发展研究 刘降斌;祃玉帅; 1-5142 我国省际数字经济高质量发展水平综合评价研究 耿娟;毕晨曦; 6-8 振兴龙江《交通科技与管理》投稿邮箱&#xff1a;cn7kantougao163.com(注明投稿“《交通科技与管理》”) 数…

首席执行官Adam Selipsky解读“亚马逊云科技的技术产品差异化”

迄今为止&#xff0c;亚马逊云科技已经参与了21世纪几乎所有的大型计算变革&#xff0c;亚马逊云科技是一个很传奇的故事&#xff0c;它始于大约20年前的一项实验&#xff0c;当时亚马逊试图出售其过剩的服务器。人们确实对此表示怀疑。为什么在线书店试图销售云服务&#xff1…

苍穹外卖总结

前言 1、软件开发流程 瀑布模型需求分析//需求规格说明书、产品原型↓ 设计 //UI设计、数据库设计、接口设计↓编码 //项目代码、单元测试↓ 测试 //测试用例、测试报告↓上线运维 //软件环境安装、配置第一阶段&#xff1a;需求分析需求规格说明书、产品原型一般来说…

React Hooks 全解:零基础入门

Hooks 的由来 你还在为该使用无状态组件&#xff08;Function&#xff09;还是有状态组件&#xff08;Class&#xff09;而烦恼吗&#xff1f; ——拥有了hooks&#xff0c;你再也不需要写Class了&#xff0c;你的所有组件都将是Function。 你还在为搞不清使用哪个生命周期钩…

Linux: 使用 ssh 连接其他服务器

通过ifconfig 查看要连接的服务器地址&#xff1a; ubuntuubuntu1804-0172:/media/sangfor/vdc$ ssh ubuntu192.168.11.49 输入要连接的服务器密码: ubuntua192.168.1149 s password: 连接服务器成功&#xff1a;

投递技术类简历的注意事项

简历修改的背景 作为程序员&#xff0c;随着工作年限的增加&#xff0c;要定期的去修改自己的简历中的工作项目&#xff0c;一方面可以促进自己复盘一下工作成果和个人成长&#xff0c;另外也能给自己换工作提供一个前置的便捷性。 注意事项 修改简历的时候有哪些需要注意的…

MySQL 视图

目录 一、视图概述 二、视图的作用和优点 三、视图的使用规则 四、视图操作 1、创建视图 2、查看视图 1&#xff09;查看视图基本信息 2&#xff09;查看视图详细信息 3、修改视图 4、更新视图 5、删除视图 一、视图概述 视图是数据库中的一个虚拟表&#xff0c;同真…

HRS--人力资源系统(Springboot+vue)--打基础升级--(六)分页查询 + 重置按钮

一&#xff1a;先弄个简单的重置按钮 1.界面设计就放在搜索框同一列的位置 2. 在点击重置按钮时&#xff0c;清空搜索框内的内容&#xff0c;同时触发一次无条件查询(这个写法有bug&#xff0c;下面会有说明) 二&#xff1a;做分页 在MyBatis中&#xff0c;有多种方法可以实现分…

【LeetCode】416.分割等和子集

题目 给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集&#xff0c;使得两个子集的元素和相等。 示例 1&#xff1a; 输入&#xff1a;nums [1,5,11,5] 输出&#xff1a;true 解释&#xff1a;数组可以分割成 [1, 5, 5] 和 [11] 。 示…

Vue2-快速搭建pc端后台管理系统

一.推荐二次开发框架 vue-element-admin Star(84k)vue-antd-admin Star(3.5k) 二.vue-element-admin 官网链接:https://panjiachen.github.io/vue-element-admin-site/zh/ 我这里搭建的是基础模版vue-admin-template(推荐) # 克隆项目 git clone https://github.com/PanJi…

VBJSON报错:缺少:语句结束

项目中使用JSON库VBJSON时报错&#xff1a; 编译错误&#xff1a;缺少&#xff1a;语句结束 cJSONScript和cStringBuilder报相同的错误&#xff0c;都在第一行: VERSION 1.0 CLASS 研究了半天没啥结果&#xff0c;之前使用这个库的时候没有什么问题&#xff0c;所以判定是当前…

MySQL 游标

文章目录 1.游标是什么2.MySQL 游标3.定义游标4.打开游标5.提取数据6.关闭游标参考文献 1.游标是什么 游标&#xff08;Cursor&#xff09;是一种用于处理查询结果集的数据库对象&#xff0c;它允许开发者按照特定的顺序逐行遍历查询结果集中的数据。游标通常用于在数据库中执…

mysql 字符集、比较规则, 比较规则底层逻辑

字符集的级别 show variables like ‘%charecter%’&#xff1b; character_set_server 服务器级别 一般在 5.7&#xff1a; C:\ProgramData\MySQL\MySQL Server 5.7\my.ini 8.0&#xff1a; C:\ProgramData\MySQL\MySQL Server 5.7\my.ini Linux 系列 vim /etc/my.cnf chara…

基于Spark框架的新闻推荐系统的设计与实现

1.摘要 离线ALS算法,以及基于内容的推荐算法进行结合.实时计算部分,使用Spark平台上的Spark Streaming流处理技术,处理日志收集框架Flume收集的日志信息. 2.需要的技术 jieba分词工具 LDA分词处理技术 LDA(Latent Dirichlet Allocatio

Debezium系列之:深入理解Debezium Server Operator和实际应用Debezium Server Operator案例详解

Debezium系列之:深入理解Debezium Server Operator和实际应用Debezium Server Operator案例详解 一、认识Debezium Server Operator二、深入理解Debezium Server和Debezium Server实际应用案例详解三、Debezium Server Operator安装步骤四、Debezium Operator使用案例五、post…

P5739 【深基7.例7】计算阶乘

题目描述 求 n ! n! n!&#xff0c;也就是 1 2 3 ⋯ n 1\times2\times3\dots\times n 123⋯n。 挑战&#xff1a;尝试不使用循环语句&#xff08;for、while&#xff09;完成这个任务。 输入格式 第一行输入一个正整数 n n n。 输出格式 输出一个正整数&#xff0c…

解决:Docker Desktop Unexpected WSL error

1、Windows中WSL2&#xff08;子系统&#xff09;安装前提条件 版本&#xff1a;win10专业版 对于 x64 系统&#xff1a;版本 1903 或更高版本&#xff0c;采用 内部版本 18362 或更高版本。 低于 18362 的版本不支持 WSL 2。 使用 Windows Update 助手更新 Windows 版本 2…

【广州华锐互动】VR高校虚拟实验教学平台提供丰富的资源支持,提高教学效果

随着科技的不断进步&#xff0c;虚拟现实(VR)技术已经逐渐渗透到各个领域&#xff0c;其中包括教育。 广州华锐互动利用VR虚拟现实技术打造的VR高校虚拟实验教学平台&#xff0c;是一种新型的教学工具&#xff0c;它提供了一个在线的教学资源管理平台&#xff0c;包含教学平台、…

电阻器件的分类

电阻器的种类碳膜电阻膜式电阻器中的一种。气态碳氢化合物在高温和真空中分解&#xff0c;碳沉积在瓷棒或者瓷管上&#xff0c;形成一层结晶碳膜。改变碳膜厚度和用刻槽的方式变更碳膜的长度可以得到不同的阻值。碳膜电阻成本较低&#xff0c;电性能和稳定性较差&#xff0c;一…