#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;
/*
判断单链表中是否有环
方法一:
使用p,q两个指针,p总是向前走,但q每次都从头开始走,对于每个节点
看p走的步数是否和q一样。
方法二:
使用p、q两个指针,p每次向前走一步,q每次向前走两步,若在某个时候p==q
则存在环
*/
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));
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;
int pos1=0;
while(cur1)
{
LinkList cur2=L;
int pos2=0;
while(cur2)
{
if(cur2==cur1)
{
if(pos1==pos2)
{
break;
}
else
{
printf("环的位置在第%d个结点处.\n",pos2);
return 1;
}
}
cur2=cur2->next;
pos2++;
}
cur1=cur1->next;
pos1++;
}
return 0;
}
/*
**判断是否有环
*/
int HasLoop2(LinkList L)
{
int step1=1;
int step2=2;
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("p:%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 temp;
i=InitList(&L);
printf("初始化L后:ListLength(L)=%d\n",ListLength(L));
printf("\n1.创建有环链表(尾插法)\n2.创建无环链表(头插法)\n3.判断两遍了是否有环\n0.退出\n");
while(opp!='0')
{
scanf("%c",&opp);
switch(opp)
{
case '1':
CreateListTail(&L,20);
printf("成功创建有环L(尾插法)\n");
printf("\n");
break;
case '2':
CreateListHead(&L,20);
printf("成功创建无环L(头插法)\n");
printf("\n");
break;
case '3':
printf("方法一:\n\n");
if(HasLoop1(L))
{
printf("结论:链表有环\n\n");
}
else
{
printf("结论:链表无环\n\n");
}
printf("方法二:\n");
if(HasLoop2(L))
{
printf("结论:链表有环\n\n");
}
else
{
printf("结论:链表无环\n\n");
}
printf("\n");
break;
case '0':
exit(0);
}
}
return 0;
}
判断单链表是否有环
最新推荐文章于 2022-08-09 23:31:45 发布