判断链表是否带环,以及环的入口

给出一个链表,先判断链表是否带环,如果带环,求出环的入口。

判断是否带环:用快慢指针。快指针每走两步,慢指针走一步,如果两者在某个点处相

遇,则链表带环。

下边给出函数的实现代码:

typedef struct LinkNode
{
	DataType data;
	struct LinkNode *next;
}LinkNode,*pLinkNode;
typedef struct LinkList
{
	LinkNode *pHead;
}LinkList,*pLinkList;
pLinkNode isCircle(pLinkList plist)
{
	assert(plist);
	if (NULL == plist->pHead)
	{
		printf("链表为空\n");
		return NULL;
	}
	pLinkNode fast = plist->pHead;
	pLinkNode slow = plist->pHead;
	while (fast && fast->next)
	{
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow)
			return fast;
	}
	return NULL;
}

如果

如果链表带环,看下边的图:

代码:

pLinkNode firstCrossNode(pLinkList plist)
{
	assert(plist);
	if (NULL == plist->pHead)
	{
		printf("链表是空\n");
		return NULL;
	}
	pLinkNode ret = isCircle(plist);
	if (ret == NULL)
	{
		printf("链表不带环\n");
		return NULL;
	}
	pLinkNode fast = plist->pHead;
	pLinkNode slow = ret;
	while (fast)
	{
		fast = fast->next;
		slow = slow->next;
		if (fast == slow)
			return fast;
	}
}
时间: 2024-10-09 10:59:19

判断链表是否带环,以及环的入口的相关文章

判断链表是否带环,若带环,找到环的入口点

#pragma once #include<iostream> using namespace std; template<class T> struct LinkNode { T _data; LinkNode* _next; LinkNode(const T& x) :_data(x) , _next(NULL) {} }; template<class T> class ListNode { //为了安全性 private: ListNode(const 

C语言强化(七)链表相交问题_3 判断链表是否带环

前两篇讨论的前提都是链表是无环的,但是如果链表有环呢? 显然,如果链表有环,那么之前的寻找链表尾结点的函数将陷入死循环,之前的算法也将崩掉. 所以对于链表相交的问题,首先要判断的是链表是否有环. 题目 给出俩个单向链表的头指针,比如 h1,h2,判断这俩个链表是否相交 解题步骤 判断两个[无环]链表是否相交 找到两个[无环]链表的相交结点 判断链表是否带环 判断两个[有环]链表是否相交 找到两个[有环]链表的相交结点 思路 用两个指针,一个指针步长为1,一个指针步长为2,若最后相遇,则链表有环

链表:判断链表是否带环 、求两个链表的相交结点

问题一:返回两个链表的相交结点1.先分别得到两个链表的长度2.得到长度差,3.先让长链表的头结点走(长度差)步.4.这时.短链表头结点还在原地,两者开始一起走,当得到两者val相等时,这个结点就是公共结点,即相遇结点. 问题二:判断链表是否带环1.定义两个快慢指针,快指针先走两步,慢指针再走一步.直到快慢指针当前结点相同. 如果快指针先为null,则表示没有环,返回null.2.如果带环,让起点和相遇点同时出发.同走一步,再判断相等与否,如果相等退出循坏 返回这个结点 ```public cla

关于相交链表、带环链表、链表深拷贝的思路整理

返回相交链表的交点:1.先求出两个链表的各自长度2.让长的先走他们的(长度差)步3.然后两者同时走,第一次相遇就是交点(返回该结点) 判断链表是否带环:1.快慢指针(快的走两步,慢的走一步,不能一个一步,一个n步(N>2),可能会错过)2.如果两个指针相遇,则链表带环:如果快的遇到null,则不带环(直线形) 求入环点:1).转化为相交问题(求取相遇结点)2).一个从起点,一个从交点,都每次走一步,第一次相遇点为入环点 相交+带环(六种情况) 复杂链表的复制1)简单复制无法解决(因为是浅拷贝)2

&lt;笔试&gt;&lt;面试&gt;C/C++单链表相关(4)判断两链表是否相交,求交点(链表不带环/可能带环)

判断两链表是否相交,求交点(假设链表不带环) 判断两链表是否相交,求交点(假设链表可能带环) RingEntry_Point()等函数见前篇. SListNode* Intersect(SListNode *&L, SListNode *&M)//判断两链表是否相交,求交点(假设链表不带环) {  //思路:若不带环,只有相交/不想交两种情况  // 与RingEntry_Point()函数方法相同:  //     求两个链表长度之差K,再令一个指针从长链表开始先走K步,令另一个指针从短

笔试,面试,C/C++,判断单链表是否带环?若带环,求环长度,求环入口点(两种方法)

SListNode* IsRing(SListNode *&pHead) //判断链表是否有环,求相聚点 {  //判空.有.没有  //思路:两个指针从头开始一快(2步)一慢(1步),若最后可以相聚,则链表有环  if (pHead)  {   SListNode *fast = pHead;   SListNode *slow = pHead;   while (fast&&fast->next)   {    fast = fast->next->next;

《编程之美》3.6判断链表是否相交之扩展:链表找环方法证明

先看看原题:<编程之美>3.6编程判断两个链表是否相交,原题假设两个链表不带环. 为了防止剧透使得没看过原题目的读者丧失思考的乐趣,我把最好的解法隐藏起来.由于这个问题本身的解答并不是本文的重点,扩展问题也采用这种形式呈现. 注:位于(*)符号之间的文字出自于:http://blog.csdn.net/v_july_v/article/details/6447013,作者v_JULY_v. 用指针p1.p2分别指向两个链表头,不断后移:最后到达各自表尾时,若p1==p2,那么两个链表必相交 用

判断链表是否有环及入口点

判断链表是否有环方法--快慢指针 一. 问:如何判断是否有环? 答:如果有两个头结点指针,一个走的快,一个走的慢,那么若干步以后,快的指针总会超过慢的指针一圈. 设置两个指针(fast,slow),初始值都指向头,slow每次前进一步,fast每次前进二步,如果链表存在环,则fast必定先进入环,而slow后进入环,两个指针必定相遇.(当然,fast先行头到尾部为NULL,则为无环链表). #include <stdio.h> typedef struct ListNode { int val

如何判断链表中是否有环

1.如何判断是否有环?如果有两个头结点指针,一个走的快,一个走的慢,那么若干步以后,快的指针总会超过慢的指针一圈. 2.如何计算环的长度?第一次相遇(超一圈)时开始计数,第二次相遇时停止计数. 3.如何判断环的入口点:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点.头指针开始走,相遇的那个点就是连接点. 为什么呢?需要一个简单的计算过程: (1)当fast与slow相遇时,show肯定没有走完链表,而fast已经在还里走了n(n>= 1)圈.假设slow走了s步,那么fast走