您的位置:首页 > 其它

判断单链表是否有环

2016-03-19 20:25 204 查看
方法一:快慢指针法。设两个工作指针,一个快一个慢,如果有环的话,它们会必然在某点相遇。

#include <iostream>
using namespace std;
typedef int ElemType;
struct Node{
ElemType data;
Node *next;
};
Node* Create()
{
Node *head,*p,*q;
head=new Node;
q=head;
int n,i;
double k;
cout<<"请输入您要创建的链表长度:";
cin>>n;
cout<<endl;
cout<<"请输入链表中每个结点保存的数据:";
for(i=0;i<n;i++)
{
cin>>k;
p=new Node;
p->data=k;
q->next=p;
q=p;
}
p->next=head->next->next;
cout<<endl<<"链表创建成功"<<endl;
return head;
}
//利用快慢指针,设两个工作指针,一个快一个慢,如果有环的话,它们必然会在某点相遇
bool JudgeCircle(Node *head)
{
Node *p,*q;
p=q=head;
while(p->next!=NULL&&q->next!=NULL)
{
p=p->next;
if(q->next!=NULL)
q=q->next->next;
if(p==q) return 1;
}
return 0;
}
int main()
{
int i;
Node *head;
head=Create();
i=JudgeCircle(head);
cout<<i<<endl;
return 0;
}


方法二. 数步数法

设两个工作指针p、q,p总是向前走,但q每次都从头开始走,对于每个节点,看p走的步数是否和q一样。比如p从A走到D,用了4步,而q则用了14步。因而步数不等,出现矛盾,存在环。

//if two pointer are equal, but they don't have the same steps, then has a loop
int HasLoop(LinkList L)
{
LinkList cur1 = L;  // 定义结点 cur1
int pos1 = 0;       // cur1 的步数
while(cur1){        // cur1 结点存在
LinkList cur2 = L;  // 定义结点 cur2
int pos2 = 0;       // cur2 的步数
pos1 ++;            // cur1 步数自增
while(cur2){        // cur2 结点不为空
pos2 ++;        // cur2 步数自增
if(cur2 == cur1){   // 当cur1与cur2到达相同结点时
if(pos1 == pos2)    // 走过的步数一样
break;          // 说明没有还
else                // 否则
return 1;       // 有环并返回1
}
cur2 = cur2->next;      //  如果没发现环,继续下一个结点
}
cur1 = cur1->next;  // cur1继续向后一个结点
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: