0
点赞
收藏
分享

微信扫一扫

[数据结构] 单链表如何判环以及求环的长度,入口

目录

​​如何判环?​​

​​如何求环的长度?​​

​​如何求环的入口呢?​​

​​示例​​

如何判环?

思路: 利用两个移动速度不同的指针,若在均不为空的情况下相遇,则存在环

如何求环的长度?

思路:若存在环,那么快慢指针从相遇点重新出发到再次相遇的过程中, 一定是慢指针走了一圈,快指针走了两圈, 慢指针所走过的步数即为环的长度

如何求环的入口呢?

推理:

[数据结构] 单链表如何判环以及求环的长度,入口_数据结构

 

 所以,我们在相遇点位和链表的起点分别设立两个速度相同的指针,当他们相遇时即在环的入口

示例

其中测试数据的关系如图

[数据结构] 单链表如何判环以及求环的长度,入口_数据结构_02

#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;
}

输出:

[数据结构] 单链表如何判环以及求环的长度,入口_数据结构_03

 


举报

相关推荐

0 条评论