题目:
有一个链表,我们需要判断链表中是否存在环。有环则输出true,否则输出false。
输入有多行,每行为由空格分隔的两个整数m和n,m是当前结点的数据,n代表当前结点的指针域指向第n个结点。
n存在四种情形:
①为-1,代表该结点的指针域指向NULL,输入结束;
②指向该结点之前的结点,如第3个结点的指针域指向n = 2的结点;
③指向自己,如第3个结点的指针域指向n = 3的结点;
④指向其直接后继结点,如第3个结点的指针域指向n = 4的结点,不能指向n = 5的结点。
当输入为:
1 2
2 3
3 -1
时,代表:第1个结点的数据为1,指向第2个结点;第2个结点的数据为2,指向第3个结点;第3个结点的数据为3,指向NULL,输入结束。
样例输入
1 2 3 3 4 2 5 -1
样例输出
true
分析:先按正常顺序建好链表,之后遍历链表调整指向,最后再遍历判断节点是否被重复访问。
代码:
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct node
{
int data;
node *next;
int x=0;
} ;
int num[1000];
int main()
{
int m,n;
memset(num,0,sizeof(num));
node *head=NULL,*p=NULL,*q=NULL;
int i=1;
while(scanf("%d%d",&m,&n)!=EOF)//先按正常顺序建立链表
{
num[i]=n;
i++;
p=new node;
p->data=m;
if(head==NULL)
head=p;
else
q->next=p;
q=p;
if(n==-1)
break;
}
//q->next=NULL;
i=1;
p=head;
while(p->next)//修改链表的指向
{
if(num[i]!=i+1)
{
if(num[i]==-1)
break;
q=head;
for(int j=1;j<num[i];j++)
q=q->next;
p->next=q;
break;
}
p=p->next;
i++;
}
p=head;
int flag=0;
while(p->next)//判断某个节点是否被重复访问
{
if(!p->x)
p->x=1;
else
{
flag=1;
break;
}
p=p->next;
}
if(flag)
cout<<"true"<<endl;
else
cout<<"false"<<endl;
return 0;
}