判断一个单向链表中是否有环
2013-05-04 12:33
357 查看
一段代码判断一个单向链表中是否有环。
下面为链表中的结构体节点
struct node
{
int data;
node *next;
}*linklist,*s,*t;
方法一:
最简单的思路就是,定义一个指针数组,初始化为空指针,从链表的头指针开始往后遍历,每次遇到一个指针就跟指针数组中的指针相比较,若没有找到相同的指针,说明这个节点是第一次访问,还没有形成环,将这个指针添加到指针数组中去。若在指针数组中找到了同样的指针,说明这个节点已经被访问过了,于是就形成了环。
方法二:
使用map来进行映射。首先定义 map<node*,int>m; 意思就是将一个node* 指针映射成数组的下标,并赋值为一个int类型的数值。
从链表的头指针开始往后遍历(p=p->next;),每次遇到一个指针p,就判断if(m[p]==0) m[p]=1;说明这个节点是第一次访问,if(m[p]==1) 说明这个节点已经被访问过一次了,于是就形成了环。
#include "iostream"
#include "map"
using namespace std;
map<node*,int>m;
bool IsLoop(node *head)
{
if(!head)
return false;
node *p=head;
while(p)
{
if(m[p]==0) // 默认值都是0
m[p]=1;
else if(m[p]==1)
return true;
p=p->next;
}
}
方法三:
思路:
用两个指针,pSlow,pFast,就是一个慢一个快
慢的一次跳一步
快的一次跳两步
往链表末端移动。如果pFast==NULL,则说明链表没有环,如果pSlow==pFast,则说明链表存在环。
这个方法与前面2个方法相比,不但速度很快,而且不需要额外的存储空间,时间复杂度、空间复杂度都是最小的。
完整的测试代码如下:
1->2->3->4->5->6->7->8 最后8又指向了4,构成了一个环
下面为链表中的结构体节点
struct node
{
int data;
node *next;
}*linklist,*s,*t;
方法一:
最简单的思路就是,定义一个指针数组,初始化为空指针,从链表的头指针开始往后遍历,每次遇到一个指针就跟指针数组中的指针相比较,若没有找到相同的指针,说明这个节点是第一次访问,还没有形成环,将这个指针添加到指针数组中去。若在指针数组中找到了同样的指针,说明这个节点已经被访问过了,于是就形成了环。
方法二:
使用map来进行映射。首先定义 map<node*,int>m; 意思就是将一个node* 指针映射成数组的下标,并赋值为一个int类型的数值。
从链表的头指针开始往后遍历(p=p->next;),每次遇到一个指针p,就判断if(m[p]==0) m[p]=1;说明这个节点是第一次访问,if(m[p]==1) 说明这个节点已经被访问过一次了,于是就形成了环。
#include "iostream"
#include "map"
using namespace std;
map<node*,int>m;
bool IsLoop(node *head)
{
if(!head)
return false;
node *p=head;
while(p)
{
if(m[p]==0) // 默认值都是0
m[p]=1;
else if(m[p]==1)
return true;
p=p->next;
}
}
方法三:
思路:
用两个指针,pSlow,pFast,就是一个慢一个快
慢的一次跳一步
快的一次跳两步
往链表末端移动。如果pFast==NULL,则说明链表没有环,如果pSlow==pFast,则说明链表存在环。
这个方法与前面2个方法相比,不但速度很快,而且不需要额外的存储空间,时间复杂度、空间复杂度都是最小的。
bool IsLoop(node *head) { node *pSlow=head; node *pFast=head; while(pSlow!=NULL && pFast!=NULL) { pSlow=pSlow->next; pFast=pFast->next->next; if(pSlow==pFast) return true; } return false; }
完整的测试代码如下:
#include "iostream"
#include "map"
using namespace std;
struct node
{
int data;
struct node *next;
}*linklist,*s,*head;
map<node*,int>m;
bool IsLoop(node *head) { node *pSlow=head; node *pFast=head; while(pSlow!=NULL && pFast!=NULL) { pSlow=pSlow->next; pFast=pFast->next->next; if(pSlow==pFast) return true; } return false; }
node* InsertNode(node *head,int value)
{
if(head==NULL)
{
head=(node *)malloc(sizeof(node));
if(head==NULL)
printf("malloc failed");
else
{
head->data=value;
head->next=NULL;
}
}
else
{
node *temp=(node *)malloc(sizeof(node));
if(temp==NULL)
printf("malloc failed");
else
{
temp->data=value;
temp->next=head;
head=temp;
}
}
return head;
}
int main(void)
{
node *t,*q,*p=NULL;
p=InsertNode(p,8);
p=InsertNode(p,7);
p=InsertNode(p,6);
p=InsertNode(p,5);
p=InsertNode(p,4);
q=p;
p=InsertNode(p,3);
p=InsertNode(p,2);
p=InsertNode(p,1);
t=p;
while(t->next) // 找到链表的尾指针
t=t->next;
t->next=q; // 将链表的尾指针指向第四个节点,这样就构成了一个环
bool flag=IsLoop(p);
if(flag)
cout<<"这个链表存在一个环"<<endl;
else
cout<<"这个链表不存在一个环"<<endl;
system("pause");
return 0;
}
1->2->3->4->5->6->7->8 最后8又指向了4,构成了一个环
相关文章推荐
- 判断一个单向链表是否形成了环状结构
- 判断一个单向链表是否有环和判断一个单向链表是否是循环链表
- 写一段代码判断一个单向链表中是否有环
- 如何判断一个单向链表是否为回文链表(Palindrome Linked List)
- 判断一个单向链表上是否有环
- 判断一个单向链表是否有环和判断一个单向链表是否是循环链表
- 判断一个单向链表中是否存在环
- 判断一个单向链表是否有环和判断一个单向链表是否是循环链表
- 判断一个单向链表中是否有环
- 题目:①判断一个单向链表是否有环,如果有环则找到环的入口节点。 ②判断两个单向链表是否相交,如果相交则找到交点节点。
- 判断一个单向链表中是否存在环
- 如何判断一个单向链表是否有环路?
- 判断一个单向链表中是否有环
- 剑指offer面试题15——扩展2:判断一个单向链表是否形成环结构
- 状下算法可以判断一个单向链表中是否有环
- 判断一个单向链表是否有环
- 判断一个单向链表中是否有环
- 剑指-判断一个单向链表是否形成了环形结构
- 判断一个单向链表中是否存在环
- 判断一个单向链表是否有环和判断一个单向链表是否是循环链表