题目:
有一个链表,我们需要判断链表中是否存在环。有环则输出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; }