判断单链表是否有环

      单链表是最常见的数据结构,带环的单链表不是很常见,但是在许多面试中出现的概率较高,其中不乏一些经典的问题,怎样判断单链表中是否有环。

      单链表带环指的是如下这张图所示情况:


      其实思想还是挺简单的:

      我们需要两个指针,初始时都指向链表的头,之后指针同时移动,其中一个指针一次移动一步,另一个指针一步移动两步,如果两个指针有相等的可能,则链表就是有环的,否则,出现一个指针指向了 NULL ,那么这个链表就是肯定不带环的。

      下面给出具体的实现:

#include <stdio.h>
#include <malloc.h>

typedef int DataType;

typedef struct node
{
	DataType data;
	struct node *next;
}LinkedNode, *LinkList;

LinkList create_list(int *a, int pos, int len);
int is_exist_loop(LinkList list);

int main(int argc, char **argv)
{
	int array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
	LinkList list_head = NULL;
	int result = -1;

	list_head = create_list(array, 10, sizeof(array) / sizeof(int));

	result = is_exist_loop(list_head);
	if(result == 0)
	{
		printf("This list has loop\n");
	}
	else if(result == -1)
	{
		printf("This list don't has loop\n");
	}
	else
	{
		printf("error\n");
	}
}

/*根据条件建立单链表*/
/*
 * a 链表初始化数组
 * pos 环的位置,若为 0 或者大于 数组长度则不带环
 * len 数组的长度
 */
LinkList create_list(int *a, int pos, int len)
{
	LinkedNode *temp = NULL; 
	int i = 0;
	LinkedNode *record = NULL;
	LinkedNode *list_head = NULL;
	LinkedNode *p = NULL;

	if(a == NULL)
	{
		return NULL;
	}
	if(pos == 0 || pos > len)
	{
		record = NULL;
	}
	list_head = (LinkedNode*)malloc(sizeof(LinkedNode));
	list_head->data = a[0];
	list_head->next = NULL;
	temp = list_head;
	for(i = 1; i < len; i++)
	{
		while(temp->next != NULL)
		{
			temp = temp->next;
		}
		p = (LinkedNode *)malloc(sizeof(LinkedNode));
		p->data = a[i];
		p->next = NULL;
		temp->next = p;
		if((i + 1) == pos)
		{
			record = p;
		}
	}
	temp = list_head;
	while(temp->next != NULL)
	{
		temp = temp->next;
	}
	temp->next = record;
	return list_head;
}

/*判断单链表是否带环*/
int is_exist_loop(LinkList list)
{
	int result = -1;
	LinkedNode *one_step = NULL;
	LinkedNode *two_step = NULL;
	one_step = list;
	two_step = list;
	while(two_step != NULL && two_step->next != NULL)
	{
		one_step = one_step->next;
		two_step = two_step->next->next;
		if(one_step == two_step)
		{
			result = 0;
			break;
		}
	}
	return result;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值