单向链表环问题的全面解析(判断环,环的长度,环的入口)
参照博客https://my.oschina.net/u/2360415/blog/741253
#include <iostream>
using namespace std;
struct Node
{
Node(int x)
{
value = x;
next = 0;
}
int value;
Node *next;
};
int getListLength(Node* head)
{
Node *slow = head;
Node *fast = head;
while (fast&&fast->next)
{
slow = slow->next;
fast = fast->next->next;
if (fast == slow)
break;
}//如果有环,循环结束后,slow=fast是碰撞点--------------------------------
//因为没有环的情况下,fast有可能停留在NULL位置,也有可能停留在最后一个节点处
//得加上fast->next==NULL
if (fast == NULL||fast->next==NULL)//无环
{
int len = 0;
Node *p = head;
while (p)
{
len++;
p=p->next;
}
//省略
return len;
}
else
{
int len1 = 0, len2 = 0;//len1是头节点到入口点的节点数(不含入口节点),len2是环所有的节点数
Node *p1 = slow;
Node *p2 = head;
while (p1)
{
len1++;
p1 = p1->next;
p2 = p2->next;
if (p1 == p2)
break;
}//循环结束后p1=p2是环的入口节点-------------------------------
while (slow)//固定碰撞点fast指针
{
len2++;
slow = slow->next;
if (slow == fast)
break;
}
cout << "环长:" << len2 << endl;
return len1 + len2;
}
}
int main()
{
Node *p1 = new Node(1);
Node *p2 = new Node(2);
Node *p3 = new Node(3);
Node *p4 = new Node(4);
Node *p5 = new Node(5);
Node *p6 = new Node(6);
p1->next = p2;
p2->next = p3;
p3->next = p4;
p4->next = p5;
p5->next = p6;
p6->next = p3;//节点p3是环入口点
cout << getListLength(p1) << endl;
return 0;
}