判断单链表中环的长度等问题

本文深入探讨了单链表中环的识别、长度计算与连接点定位,通过实例代码实现,详细解释了如何利用双指针策略解决此类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

给定一个单链表,只给出头指针h:

1、判断是否存在环

选定两个指针p1,p2,初始时p1=p2=h,循环执行以下操作p1=p1+1,p2=p2+2,判断p1==p2,若p1==p2,记交点为p,则存在环,否则不存在。(追赶问题)

2、求取环的长度

从p开始执行以下操作p1=p1+1,p2=p2+2,再次相交时,执行的操作数,即为环的长度。(追赶问题)

3、找出环的连接点

p点到交点的距离=h到交点的距离。

证明:


证毕

4、带环链表的长度

s+s1

 

code---根据上图构建链表

#include <stdio.h>
#include <stdlib.h>

typedef struct chain
{
	int num;
	struct chain* next;
}CH,NODE;

NODE* newnode(void)
{
	NODE* temp;

	temp=(NODE*)malloc(sizeof(NODE));
	return temp;
}

NODE* createchain(void)
{
	int i;
	NODE* temp,*save=NULL,*h,*p;

	for(i=1;i<=7;i++)
	{
		temp=newnode();
		temp->num=i;
		if(save==NULL)
		{
			save=temp;
			h=save;
		}
		else
		{
			save->next=temp;
			save=temp;
		}

		if(i==4)
		{
			p=save;
		}
	}
	save->next=p;

	return h;
}

void checkloop(NODE* h)
{
	int len1=0,len2=0;
	NODE* p1,*p2;

	p1=p2=h;
	p1=p1->next;
	p2=p2->next->next;

	while(p1!=p2)
	{
		p1=p1->next;
		p2=p2->next->next;
	}

	len1=1;
	p1=p1->next;
	p2=p2->next->next;
	while(p1!=p2)
	{
		p1=p1->next;
		p2=p2->next->next;
		len1++;
	}
	printf("The length of the loop is: %d\n",len1);

	p1=h;
	while(p1!=p2)
	{
		len2++;
		p1=p1->next;
		p2=p2->next;
	}
	printf("The intersect node is: %d\n",p1->num);
	printf("The length of the chain is: %d\n",len1+len2);
}

int main(void)
{
	CH* h;

	h=createchain();
	checkloop(h);

	system("pause");
	return 0;
}



在C++中计算形链表中环长度,通常可以采用“快慢指针”(Floyd's Cycle Detection Algorithm)的方法。这种方法利用两个指针,一个移动一步,另一个移动两步,如果存在,则最终它们会在内相遇。相遇点到链表头的距离就是长度。 以下是基本步骤: 1. 首先初始化两个指针`slow`和`fast`,分别指向链表的头节点。 2. 如果链表不是形的,`fast`会先到达`nullptr`,这时返回0,表示无。 3. 否则,当`fast`遇到`slow`时,说明找到了,此时记录下`fast`的位置。 4. 将`slow`重新设回链表头,然后同时移动`slow`和`fast`,每次`slow`走一步,`fast`走两步,直到它们再次相遇。 5. 此时,`slow`距离的起点就是长度,因为`fast`比`slow`多走了整个的一圈。 这里是简单的C++代码示例: ```cpp #include <iostream> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; ListNode* detectCycle(ListNode* head) { if (head == nullptr || head->next == nullptr) return nullptr; // 检查是否有 ListNode slow(*head); ListNode fast(*head); while (fast != nullptr && fast->next != nullptr) { slow = slow.next; fast = fast.next->next; if (slow == fast) { // 找到了 slow = head; // 将slow重新置回到头 while (slow != fast) { slow = slow.next; fast = fast.next; } return &slow; // 返回的起点 } } return nullptr; // 不存在 } int main() { // 测试代码 ListNode* ringHead = ... // 形链表头节点 ListNode* result = detectCycle(ringHead); if (result) { cout << "长度是: " << distance(head, result) << endl; // 使用distance函数计算长度 } else { cout << "链表中没有" << endl; } return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值