怎么判断一个单向链表是否有回环(笔试题)

whutcl8110 2005-11-18 01:05:08
怎么判断一个单向链表是否有回环?
即表尾指针不是空,可能指向前面的某一个接点
...全文
1863 30 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
luojxun 2005-11-20
  • 打赏
  • 举报
回复
不好意思理解有误,是种方法
luojxun 2005-11-20
  • 打赏
  • 举报
回复
有问题,如果单链足够长,快的也能追上慢的.
bombwang 2005-11-20
  • 打赏
  • 举报
回复
学习
whutcl8110 2005-11-20
  • 打赏
  • 举报
回复
谢谢大家的回答!
分不多,一人那一点
^_^!
oosky2004 2005-11-19
  • 打赏
  • 举报
回复
看清楚题目!
如果有环,并不一定指向头节点。
RedWolf1999 2005-11-19
  • 打赏
  • 举报
回复
就是,楼上说的是,让我也晕.大家发帖也要对自己的帖子负责啊.
上面那代码明显是错的.
Featured 2005-11-19
  • 打赏
  • 举报
回复
这是大公司常用的面试题,
其实在《 C专家编程》一书中有详细解答。
feelyousky 2005-11-19
  • 打赏
  • 举报
回复
用倒链技术,如果有环的话,指针会回到头结点。复杂度不会超过2N。
代码:
#include <iostream>
using namespace std;

struct mylist{
int a;
mylist* next;
};

mylist *head;
mylist *first;
mylist *second;
mylist *third;

void initial()
{
head=new mylist;
first=new mylist;
second=new mylist;
third=new mylist;
head->a=0;
first->a=1;
second->a=2;
third->a=3;
head->next=first;
first->next=second;
second->next=third;
third->next=second;
cout<<"initial"<<endl;

}
///////////////////上面是简单的链结点的定义和初始化链
void main()
{
initial();
//环的连接点,有两个点指向他,运用倒链可以查出这个点是哪个
mylist*p;
mylist*m;
mylist*n;
m=head;
p=NULL;
while(1)
{
n=m->next;
if(n==NULL)
return;
if(n==head)
{
cout<<"存在环!"<<endl;
return;
}
cout<<n->a<<endl;
m->next=p;
p=m;
m=n;
}
}
0黄瓜0 2005-11-19
  • 打赏
  • 举报
回复
暴力破解,每得到个指针都从头比较有没有相等的指针,直到遇到NULL或相等的指针。简单,但效率不高。
oosky2004 2005-11-19
  • 打赏
  • 举报
回复
对上面的代码修改了一下。如果有环的话,进入环后,pNext会追p,追到就返回1。
PLink pNext;
pNext = p;
if(!p)
{
return 0;
}

while(pNext)
{
if(p == pNext)
{
return 1;
}
p = p -> next;
pNext = pNext->next;
}
return 0;
oosky2004 2005-11-19
  • 打赏
  • 举报
回复
楼上的,有环的链表你怎么求长度?

junku_kong 2005-11-19
  • 打赏
  • 举报
回复
先求长度l,再用for从表头循环l到表尾,若此接点不指向NULL,则为回环,返回0;否则,返回1。
SLink *sq;
int l;
l=Get_length(sq);
for(int i=0;i<l;i++)
{
p=p->next;
}
if(p->next!=NULL)
return 0;
return 1;
someonehappy 2005-11-19
  • 打赏
  • 举报
回复
是不是有点问题?

PLink pNext;
if(!p)
{
return 0;
}
pNext = p;
while(pNext)
{
if(p == pNext || pNext == pNext->next)
{
return 1;
}
pNext = pNext->next;
}
return 0;


进入循环前pNext=p;,那进去以后不是必然p==pNext然后return 1么?
guyanhun 2005-11-18
  • 打赏
  • 举报
回复
学习.

不过, x86(大雪)的理解应该是错的吧.
for(p=head; p!=tail; p++) {
for(q=head; q!= p; q++) {
if(q==p->next) {
// (q, p) 是一个回环
}
}
}
如果 tail 已知的话,只需判断 tail->next 是否 == NULL 就可以了啊.
还用得着那么麻烦吗?
chenbinghui 2005-11-18
  • 打赏
  • 举报
回复
前面那个是破坏性的函数,如果申请一个变量就不会是破坏性了,
PLink pNext;
if(!p)
{
return 0;
}
pNext = p;
while(pNext)
{
if(p == pNext || pNext == pNext->next)
{
return 1;
}
pNext = pNext->next;
}
return 0;
chenbinghui 2005-11-18
  • 打赏
  • 举报
回复
while(p && p->next)
{
if(p == p->next || p->next == p->next->next)
{
return 1;
}
p->next = p->next->next;
}
return 0;
logi001 2005-11-18
  • 打赏
  • 举报
回复
定长短指针..
sankt 2005-11-18
  • 打赏
  • 举报
回复
up
寻开心 2005-11-18
  • 打赏
  • 举报
回复
快的是慢的一倍速度是不会产生跨越的,如果是2倍,3倍就不一定了

复杂度不会超过2n,

跑的快的会在慢的跑完一圈之前追上的
languagec 2005-11-18
  • 打赏
  • 举报
回复
复杂度不会超过 2n 吧
加载更多回复(10)

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧