您的位置:首页 > 理论基础 > 数据结构算法

查看链表是否有环(数据结构C++表示)

2015-07-30 16:10 495 查看
查看链表是否有环有两种方法:

方法一:声明两个指针cur1和cur2,让cur1->next每次都指向下一个结点,cur2每一次都从第一个节点指到cur1当前的结点,然后判断两个指针指向同一个节点的步数,如果步数一样,则说明还没有找到环。如果步数不一样,则说明找到环了。

方法二:声明两个指针p和q,p每次走一步,q每次走两步,然后判断p和q是否相等,如果相等的话,说明有环,因为只有在有环的状况下,q走了一圈,然后追上p点。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0

typedef int Status;
typedef int ElemType;

typedef struct Node
{
ElemType data;
struct Node *next;
}Node,*LinkList;

Status InitList(LinkList *L)
{
*L = (LinkList)malloc(sizeof(Node));

if(!(*L))
{
return ERROR;
}
(*L)->next = NULL;
return OK;
}

int ListLength(LinkList L)
{
int i=0;
LinkList p = L->next;
while(p)
{
i++;
p = p->next;
}
return i;
}

void CreateListHead(LinkList *L, int n)
{
LinkList p;
int i;

srand(time(0));

*L = (LinkList)malloc(sizeof(Node));
(*L)->next = NULL;

for(i=0; i<n; i++)
{
p = (LinkList)malloc(sizeof(Node));
p->data = rand()%100+1;
p->next = (*L)->next;
(*L)->next = p;
}
}

void CreateListTail(LinkList *L, int n)
{
LinkList p,r;
int i;

srand(time(0));
*L = (LinkList)malloc(sizeof(Node));
if(!(*L))
{
return;
}
r = *L;

for(i=0; i<n; i++)
{
p = (Node*)malloc(sizeof(Node));
p->data = rand()%100+1;
r->next = p;
r = p;
}

r->next = (*L)->next->next;
}

//比较步数的方法
int HasLoop1(LinkList L)
{
LinkList cur1 = L;   //定义结点cur1
int pos1 = 0;        //cur1的步数

while(cur1)          //cur1结点存在
{
LinkList cur2 = L;//定义结点cur2
int pos2 = 0;     //cur2的步数
while(cur2)       //cur2结点存在
{
if(cur2==cur1)
{
/*当cur1与cur2到达相同结点时
走过的步数一样,说明没有环*/
if(pos1==pos2)
{
break;
}
else
{
printf("环的位置在第%d个结点处。\n\n",pos2);
return 1; //有环并返回1
}
}
cur2 = cur2->next;
pos2++;
}
cur1 = cur1->next;
pos1++;
}
return 0;
}

int HasLoop2(LinkList L)
{
LinkList p = L;
LinkList q = L;

while(p!=NULL && q!=NULL && q->next!=NULL)
{
p = p->next;
if(q->next != NULL)
{
q = q->next->next;
}

printf("q:%d, q:%d\n",p->data, q->data);

if(p==q)
{
return 1;
}
}
return 0;
}

int main()
{
LinkList L;
Status i;
char opp;
ElemType e;
int find;
int tmp;

printf("\n1.创建有环链表(尾插法) \n2.创建无环链表(头插法) \n3.判断链表是否有环 0.退出\n\n");
while(opp != '0')
{
scanf("%c",&opp);
switch(opp)
{
case '1':
{
CreateListTail(&L,10);
printf("成功创建有环L(尾插法)\n");
break;
}
case '2':
{
CreateListHead(&L,10);
printf("成功创建有环L(头插法)\n");
break;
}
case '3':
{
printf("方法一:\n\n");
if(HasLoop1(L))
{
printf("结论:链表有环\n\n\n");
}
else
{
printf("结论:链表无环\n\n\n");
}

printf("方法二:\n\n");
if(HasLoop2(L))
{
printf("结论:链表有环\n\n\n");
}
else
{
printf("结论:链表无环\n\n\n");
}
printf("\n");
break;
}
case '0':
{
exit(0);
break;
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  链表 指针