王道p40 21.单链表有环,是指单链表的最后一个结点的指针指向了链表中的某个结点(通常单链表的最后一个结点的指针域是空的)。试编写算法判断单链表是否存在环。(c语言代码实现)

本题设置快慢两个指针,快指针每次走两步,慢指针每次走一步,如果有环,他们肯定会相遇,相遇点就是环的入口点

本题代码如下

linklist find(linklist* L)
{
	lnode* f = *L, * s = *L;//设置快慢两个指针
	while (s != NULL && f->next != NULL)
	{
		s = s->next;//每次走一步
		f = f->next->next;//每次走两步
		if (s->data == f->data)//相遇
			break;
	}
	if (s == NULL || f->next == NULL)
		return NULL;//没有环,返回NULL
	lnode* p = *L, * q = s;//分开指向开始点、相遇点
	while (p->data != q->data)
	{
		p = p->next;
		q = q->next;
	}
	return p;//返回入口
}

完整测试代码

#include
#include
typedef struct lnode
{
	int data;
	struct lnode* next;
}lnode,*linklist;
int n = 16;
int a[16] = { 1,2,3,4,5,6,7,8,9,3,4,5,6,7,8,9 };
void buildlinklist(linklist *L)
{
	lnode* s, * r = *L;
	r->data = a[0];
	int i = 0;
	for (i = 1; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = a[i];
		r->next = s;
		r = r->next;
	}
	r->next = NULL;
}
linklist find(linklist* L)
{
	lnode* f = *L, * s = *L;//设置快慢两个指针
	while (s != NULL && f->next != NULL)
	{
		s = s->next;//每次走一步
		f = f->next->next;//每次走两步
		if (s->data == f->data)//相遇
			break;
	}
	if (s == NULL || f->next == NULL)
		return NULL;//没有环,返回NULL
	lnode* p = *L, * q = s;//分开指向开始点、相遇点
	while (p->data != q->data)
	{
		p = p->next;
		q = q->next;
	}
	return p;//返回入口
}
void print(linklist* L)
{
	lnode* k = *L;
	while (k)
	{
		printf("%d ", k->data);
		k=k->next;
	}
}
int main()
{
	linklist L=(lnode*)malloc(sizeof(lnode));
	buildlinklist(&L);
	printf("原始单链表");
	print(&L);
	lnode *ans=find(&L);
	printf("\n环口值为:%d",ans->data);
	return 0;
}

你可能感兴趣的:(王道课后习题单链表,链表,算法,c语言)