一、判断链表中是否有环
#include "stdio.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)); //
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("\n\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 tmp;
i = InitList(&L);
printf("Length(L)=%d\n", ListLength(L));
printf("\n1. 尾插法创建循环链表 \n2. 头插法创建链表\n3. 获取链表长度\n0. 退出\n\n");
while(opp != '0')
{
scanf("%c", &opp);
switch(opp)
{
case '1':
CreateListTail(&L, 20);
printf("\n");
printf("\n");
break;
case '2':
CreateListHead(&L, 20);
printf("\n");
printf("\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);
}
}
}
二、问题