目录
如何判环?
思路: 利用两个移动速度不同的指针,若在均不为空的情况下相遇,则存在环
如何求环的长度?
思路:若存在环,那么快慢指针从相遇点重新出发到再次相遇的过程中, 一定是慢指针走了一圈,快指针走了两圈, 慢指针所走过的步数即为环的长度
如何求环的入口呢?
推理:
所以,我们在相遇点位和链表的起点分别设立两个速度相同的指针,当他们相遇时即在环的入口
示例
其中测试数据的关系如图
#include<iostream>
using namespace std;
typedef struct SingleListNode{
int value;
SingleListNode* next;
SingleListNode(int v):value(v),next(NULL){}
}SLNode;
class SingleList{
public:
SLNode* phead;
SingleList();
bool isCircle(){
return firstMeet(phead) != NULL;
}
int getCircleLenth();
int getCircleEntrance();
void headInsert(int value);
private:
SLNode* firstMeet(SLNode* phead);
};
SingleList::SingleList()
{
phead = new SLNode(0);
}
void SingleList::headInsert(int value)
{
SLNode* newNode = new SLNode(value);
newNode->next = phead->next;
phead->next = newNode;
}
SLNode* SingleList::firstMeet(SLNode* phead)
{
SLNode* pslow, *pfast;
pslow = pfast = phead->next;
while(pslow && pfast) //若存在环的话两个工作指针必不会出现空的情况
{
pslow = pslow->next;
pfast = pfast->next ? pfast->next->next : pfast->next;
if(pslow->value == pfast->value) return pslow;
}
return NULL;
}
int SingleList::getCircleLenth()
{
SLNode* pfirstMeet = firstMeet(phead);
//无环的情况
if(!pfirstMeet) return 0;
SLNode* pslow, *pfast;
pslow = pfast = pfirstMeet;
int step = 0;
while(pslow && pfast)
{
pslow = pslow->next;
step ++;
pfast = pfast->next ? pfast->next->next : pfast->next;
if(pslow->value == pfast->value) return step;
}
}
int SingleList::getCircleEntrance()
{
SLNode* pfirstMeet = firstMeet(phead);
//无环的情况
if(!pfirstMeet) return -1;
SLNode* p1 = phead->next;
SLNode* p2 = pfirstMeet;
while(p1 != p2)
{
p1 = p1->next;
p2 = p2->next;
}
return p1->value;
}
int main()
{
SingleList* list = new SingleList();
SLNode* p1 = new SLNode(1);
SLNode* p3 = new SLNode(3);
SLNode* p5 = new SLNode(5);
SLNode* p7 = new SLNode(7);
SLNode* p2 = new SLNode(2);
SLNode* p4 = new SLNode(4);
p1->next = p3;
p3->next = p5;
p5->next = p7;
p7->next = p2;
p2->next = p4;
p4->next = p5;
list->phead->next = p1;
if(list->isCircle()){
cout << "存在环,且长度为: " << list->getCircleLenth() << endl;
cout << "环的入口为: " << list->getCircleEntrance();
}else{
cout << "不存在环" ;
}
return 0;
}
输出: