检查链表是否有环,返回值为bool和从头节点进入环的第一个节点两种情况

本文主要是介绍检查链表是否有环,返回值为bool和从头节点进入环的第一个节点两种情况,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目1(不返回节点)

给定单链表,检查链表是否有环。

代码实现:

bool IsCircle(List plist)
{assert(plist != NULL);if (plist == NULL||plist->next==NULL)return false;Node* p = plist->next;//慢指针,一次走一步Node* q = plist->next->next;//快指针,一次走两步while (q!= NULL&&q->next!=NULL){if (p == q){break;}else{p = p->next;q = q->next->next;}}if (q == NULL || q->next == NULL){return false;}else{return true;}}

题目2(返回节点)

给定单链表(head),如果有环的话请返回从头节点进入环的第一个节点。

思路: 

给定慢指针p->next;快指针q->next->next。如图,假设快、慢指针在点3相遇,快指针走过的路径是慢指针的两倍。

慢指针走过的路径长度:m+n
快指针走过的路径长度:m+c*x+n
快指针走过的路径是慢指针的2倍,所以,2*(m+n)=m+c*x+n

由上式得到m=c*x-n=c*x-n+c-c=c*(x-1)+c-n,即m的长度比圆的周长倍数多出c-n的长度,相遇点加上c-n的位置就是进入环的第一个节点。

代码实现:

Node* FirstCircleNode(List plist)
{assert(plist != NULL);if (plist == NULL||plist->next==NULL)return NULL;Node* p = plist->next;//慢指针Node* q = plist->next->next;//快指针for (p, q; q != NULL && q->next != NULL; p = p->next, q = q->next->next){if (p == q)break;}if (q==NULL||q->next==NULL)//没有环{return NULL;}//快慢指针相遇了Node* s = plist;//1while (s != q){s = s->next;q = q->next;}return s;
}int main()
{Node head;InitList(&head);for (int i = 0; i < 10; i++){Insert_tail(&head, i);}Show(&head);Node* p1 = FirstCircleNode(&head);if (p1!=NULL)printf("有环,%d\n",p1->data);elseprintf("无环\n");//Node* q = Search(&head, 3);//链表中的某一个节点(数据域为3)//Node* s = Search(&head, 9);//尾巴节点//s->next = q;//Node* p2 = IsCircle(&head);//if (p2 != NULL)//	printf("有环,%d\n", p2->data);//else//	printf("无环\n");Node* q = Search(&head, 5);//链表中的某一个节点(数据域为5)Node* s = Search(&head, 9);//尾巴节点s->next = q;Node* p2 = FirstCircleNode(&head);if (p2 != NULL)printf("有环,%d\n", p2->data);elseprintf("无环\n");return 0;
}

 

这篇关于检查链表是否有环,返回值为bool和从头节点进入环的第一个节点两种情况的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/771768

相关文章

检查 Nginx 是否启动的几种方法

《检查Nginx是否启动的几种方法》本文主要介绍了检查Nginx是否启动的几种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学... 目录1. 使用 systemctl 命令(推荐)2. 使用 service 命令3. 检查进程是否存在4

Android使用java实现网络连通性检查详解

《Android使用java实现网络连通性检查详解》这篇文章主要为大家详细介绍了Android使用java实现网络连通性检查的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录NetCheck.Java(可直接拷贝)使用示例(Activity/Fragment 内)权限要求

MyBatis中的两种参数传递类型详解(示例代码)

《MyBatis中的两种参数传递类型详解(示例代码)》文章介绍了MyBatis中传递多个参数的两种方式,使用Map和使用@Param注解或封装POJO,Map方式适用于动态、不固定的参数,但可读性和安... 目录✅ android方式一:使用Map<String, Object>✅ 方式二:使用@Param

python项目打包成docker容器镜像的两种方法实现

《python项目打包成docker容器镜像的两种方法实现》本文介绍两种将Python项目打包为Docker镜像的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 目录简单版:(一次成功,后续下载对应的软件依赖)第一步:肯定是构建dockerfile,如下:第二步

MySQL集群高可用架构的两种使用小结

《MySQL集群高可用架构的两种使用小结》本文介绍了MySQL的两种高可用解决方案:组复制(MGR)和MasterHighAvailability(MHA),文中通过示例代码介绍的非常详细,对大家的学... 目录一、mysql高可用之组复制(MGR)1.1 组复制核心特性与优势1.2 组复制架构原理1.3

Python版本与package版本兼容性检查方法总结

《Python版本与package版本兼容性检查方法总结》:本文主要介绍Python版本与package版本兼容性检查方法的相关资料,文中提供四种检查方法,分别是pip查询、conda管理、PyP... 目录引言为什么会出现兼容性问题方法一:用 pip 官方命令查询可用版本方法二:conda 管理包环境方法

java中判断json key是否存在的几种方法

《java中判断jsonkey是否存在的几种方法》在使用Java处理JSON数据时,如何判断某一个key是否存在?本文就来介绍三种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目http://www.chinasem.cn录第一种方法是使用 jsONObject 的 has 方法

Java8 Collectors.toMap() 的两种用法

《Java8Collectors.toMap()的两种用法》Collectors.toMap():JDK8中提供,用于将Stream流转换为Map,本文给大家介绍Java8Collector... 目录一、简单介绍用法1:根据某一属性,对对象的实例或属性做映射用法2:根据某一属性,对对象集合进行去重二、Du

Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧

《Python函数的基本用法、返回值特性、全局变量修改及异常处理技巧》本文将通过实际代码示例,深入讲解Python函数的基本用法、返回值特性、全局变量修改以及异常处理技巧,感兴趣的朋友跟随小编一起看看... 目录一、python函数定义与调用1.1 基本函数定义1.2 函数调用二、函数返回值详解2.1 有返

MySQL使用EXISTS检查记录是否存在的详细过程

《MySQL使用EXISTS检查记录是否存在的详细过程》EXISTS是SQL中用于检查子查询是否返回至少一条记录的运算符,它通常用于测试是否存在满足特定条件的记录,从而在主查询中进行相应操作,本文给大... 目录基本语法示例数据库和表结构1. 使用 EXISTS 在 SELECT 语句中2. 使用 EXIS