数据结构-判断链表中是否有环

一、判断链表中是否有环

在这里插入图片描述

#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);
		}
	}
}

二、问题
在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构能够判断是否存在的方法之一是使用快慢指针法。该方法适用于链表和图等数据结构。快慢指针法的基本思想是使用两个指针,一个指针每次移动一个节点,而另一个指针每次移动两个节点。如果存在,则两个指针最终会相遇。 另一种方法是使用深度优先搜索(DFS)或广度优先搜索(BFS)来遍历图或树。在遍历过程,如果遇到已经访问过的节点,则说明存在。 综上所述,数据结构能够判断是否存在的方法包括快慢指针法和深度优先搜索或广度优先搜索。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [算法数据结构有哪些奇技淫巧?](https://blog.csdn.net/lyshark_lyshark/article/details/126792526)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [JavaScript版数据结构与算法](https://blog.csdn.net/qq_46345868/article/details/124532434)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值