检查链表是否有环,返回值为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

相关文章

python判断文件是否存在常用的几种方式

《python判断文件是否存在常用的几种方式》在Python中我们在读写文件之前,首先要做的事情就是判断文件是否存在,否则很容易发生错误的情况,:本文主要介绍python判断文件是否存在常用的几种... 目录1. 使用 os.path.exists()2. 使用 os.path.isfile()3. 使用

SpringBoot服务获取Pod当前IP的两种方案

《SpringBoot服务获取Pod当前IP的两种方案》在Kubernetes集群中,SpringBoot服务获取Pod当前IP的方案主要有两种,通过环境变量注入或通过Java代码动态获取网络接口IP... 目录方案一:通过 Kubernetes Downward API 注入环境变量原理步骤方案二:通过

Linux链表操作方式

《Linux链表操作方式》:本文主要介绍Linux链表操作方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、链表基础概念与内核链表优势二、内核链表结构与宏解析三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势六、典型应用场景七、调试技巧与

Python如何判断字符串中是否包含特殊字符并替换

《Python如何判断字符串中是否包含特殊字符并替换》这篇文章主要为大家详细介绍了如何使用Python实现判断字符串中是否包含特殊字符并使用空字符串替换掉,文中的示例代码讲解详细,感兴趣的小伙伴可以了... 目录python判断字符串中是否包含特殊字符方法一:使用正则表达式方法二:手动检查特定字符Pytho

golang实现延迟队列(delay queue)的两种实现

《golang实现延迟队列(delayqueue)的两种实现》本文主要介绍了golang实现延迟队列(delayqueue)的两种实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的... 目录1 延迟队列:邮件提醒、订单自动取消2 实现2.1 simplChina编程e简单版:go自带的time

宝塔安装的MySQL无法连接的情况及解决方案

《宝塔安装的MySQL无法连接的情况及解决方案》宝塔面板是一款流行的服务器管理工具,其中集成的MySQL数据库有时会出现连接问题,本文详细介绍两种最常见的MySQL连接错误:“1130-Hostisn... 目录一、错误 1130:Host ‘xxx.xxx.xxx.xxx’ is not allowed

CentOS7增加Swap空间的两种方法

《CentOS7增加Swap空间的两种方法》当服务器物理内存不足时,增加Swap空间可以作为虚拟内存使用,帮助系统处理内存压力,本文给大家介绍了CentOS7增加Swap空间的两种方法:创建新的Swa... 目录在Centos 7上增加Swap空间的方法方法一:创建新的Swap文件(推荐)方法二:调整Sww

QT6中绘制UI的两种方法详解与示例代码

《QT6中绘制UI的两种方法详解与示例代码》Qt6提供了两种主要的UI绘制技术:​​QML(QtMeta-ObjectLanguage)​​和​​C++Widgets​​,这两种技术各有优势,适用于不... 目录一、QML 技术详解1.1 QML 简介1.2 QML 的核心概念1.3 QML 示例:简单按钮

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式