链表的环的问题

Ros入门 (十)----激光雷达避障 简易实现 本篇文章通过订阅/scan话题获取障碍物的距离信息,达到避障目的,提供部分代码,仅供参考。 阅读详情

简介

对于链表这一数据结构,它拥有各种类型的结构,我们知道,链表最基本的有三个特征——带头(哨兵位)结点和不带头结点、单向和双向、循环和不循环;

我们仅仅根据这三个基本特征就能将链表的结构分为大致8种情况,链表当然还有很多别的特征,更多的特征对应更多的性质,这也说明着数据结构的多样和灵活性;

那么今天这篇文章,就来向大家介绍一种特殊的链表,它类似于我们的循环链表,却又和循环链表有一定的区别,但在某些局部的性质上又存在着部分联系,难度不大但却有很多有意思的性质,能很好的锻炼我们的代码能力和逻辑思维,它就是带环链表;

1.什么是带环链表?

用一张我们最熟知的单链表和带环链表同时出现的图来向大家解释:

相信通过这张图,大家就能很清楚的初步了解到我们要介绍的带环链表,带环链表和单链表唯一的区别是,单链表的尾结点的指向下一个结点的指针为空,而带环链表的尾结点的指向下一个结点的指针是该链表上的任意一个结点,以此形成了一个类似于环形的结构,因此我们称其为带环结点;

那它和我们早知道的无头单向不循环链表有什么区别呢?单向无头不循环链表的尾结点仅仅指向的是链表的头结点,我们可以将其看做是带环链表的一个特例;

那接下来就向大家简单介绍一下链表的几个环的问题,希望能帮大家更好的理解成环的链表;

2.单链表如何形成带环链表

为了研究带环链表,我们当然需要先创建出一个带环链表,而带环链表是基于单链表实现的,要想创建出一个带环链表,我们需要先创建出一个单链表;

单链表的创建就比较基础的,头插尾插中插,这都能构造出一个单链表,这里我们就用尾插来表示吧,我们直接给出这部分相对基础的代码:

1.申请链表的一个结点pSLNode BuySListNode(SLDataType x)

2.链表尾插数据,void SListPushBack(pSLNode* pphead, SLDataType x)

3.打印出链表,void ShowSList(pSLNode phead)

pSLNode BuySListNode(SLDataType x)
{
	pSLNode newnode = (pSLNode)malloc(sizeof(SLNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}


void SListPushBack(pSLNode* pphead, SLDataType x)
{
	pSLNode newnode = BuySListNode(x);
	if (*pphead == NULL)
		*pphead = newnode;
	else
	{
		//先找到尾
		pSLNode tail = *pphead;
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}


void ShowSList(pSLNode phead)
{
	pSLNode cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}

我们可以看看效果:

int main()
{
	//Test1();
	pSLNode plist = NULL;
	int n = 0;
	//输入单链表的值,并以-1结束
	printf("请输入单链表的值,并以-1结束:>\n");
	do
	{
		scanf("%d", &n);
		if (n != -1)
			SListPushBack(&plist, n);
	} while (n != -1);
	ShowSList(plist);

	return 0;
}

这样看来,我们单链表也就构建好了,接下来就是成环的问题;

成环的方法其实很简单,我们只需要找到链表的尾结点,然后让其next指向该链表的任何一个结点就完成了,这里我们不指定尾结点的指向,我们采用随机数的方法,根据链表的长度随机生成环节点,这里就需要我们调用srand和rand函数;

我们要知道一个常识,若我们要生成一个a ~ b的随机数,比如说这个数是k,

那么k = a + rand() % (b - a + 1);我们一定要将其牢牢记住,那我们根据以上思路来实现这个算法:

void CreateCycle(pSLNode phead, int len)
{
	int k = 0 + rand() % (len - 1 - 0 + 1);
	pSLNode cur = phead;
	while (k--)
	{
		cur = cur->next;
	}
	//找尾
	pSLNode tail = phead;
	while (tail->next)
	{
		tail = tail->next;
	}
	tail->next = cur;
}

len为链表的长度,可在链表插入数据时顺便记录下来;

我们来看看效果(成环成功必然是一个死循环);

不出所料的一个死循环,可以看到,链表的尾结点指向了倒数第三个结点,成功成环;

3.如何判断链表是否成环

如果我们需要使用到带环链表,那我们就需要提前判断一下该链表是不是一个带环链表,这个问题并不复杂;

我们知道,如果我们安排一个指针依次遍历链表的每个结点,如果该链表带环,那么这个结点就永远走不到NULL,会在这个带环链表中永远循环下去,我们可以通过这个现象来得到判断链表是否带环的思路,那就是我们熟知的快慢指针;

定义两个结点指针slow和fast,slow一次走一步,fast一次走两步,如果链表带环,fast在走到尾之后会返回最初成环的点,如果slow此时已经经过原本成环的结点,fast最终就会追上slow,若slow没有经过原本成环的点,那么fast就会在环上再走一圈继续追赶slow,循环往复,最终fast和slow就会相遇,当fast和slow相遇,我们就能判断出链表确实是带环的;

倘若链表不带环,fast就会先走到NULL或者NULL的前一个结点,意味着我们判断的结果为false;

下面给出一个图示:

我们可以看到,fast走到尾后重新返回了最初成环的结点,追赶slow并与其相遇在了倒数第二个结点,我们由此来进行代码的实现:

bool IsCycle(pSLNode phead)
{
	pSLNode slow = phead;
	pSLNode fast = phead;
	while (fast && fast->next)
	{
		//slow一次走一步
		slow = slow->next;
		//fast一次走两步
		fast = fast->next->next;

		if (fast == slow)
		{
			//相遇了
			return true;
		}
	}

	//fast走到空或链表本身就为空
	return false;
}

我们也可以分装一个函数来判断这个接口的正确性:

void TestIsCycle()
{
	pSLNode plist = NULL;
	printf("请输入单链表的值,并以-1结束:>\n");
	int n = 0;
	do
	{
		scanf("%d", &n);
		if (n != -1)
		{
			SListPushBack(&plist, n);
		}
	} while (n != -1);

	int len = SlistLength(plist);
	CreateCycle(plist, len);

	bool ret = IsCycle(plist);
	if (ret == true)
	{
		printf("该链表是带环链表\n");
	}
	else
	{
		printf("该链表不是带环链表\n");
	}
}

结果展示:

我们再将成环的功能CreateCycle( )屏蔽掉

//int len = SListLength(plist);
//CreateCycle(plist, len);

bool ret = IsCycle(plist);
if (ret == true)
{
	printf("该链表是带环链表\n");
}
else
{
	printf("该链表不是带环链表\n");
}

那我们判断链表是否带环的功能就实现的差不多了,但在实现完这个功能后,我们也会不禁发出一些疑问,为什么slow走一步,fast走两步,它们最后一定会相遇,如果fast一次走3步,4步,5步,这样也是快慢指针,那他们最后也会相遇吗?接下来就让我们来探讨一下:

3.1.判断成环的延伸

我们先来讨论fast走两步的情况下最终一定能和slow相遇,这个问题其实很直观:

如下图所示:

在这个带环链表中,我们知道,slow入环前,fast早已入环,fast在环里走了多少我们无需关注,我们假设,在slow入环后,slow和fast之间的距离是N,那接下来,按照fast每次走两步,slow每次走一步来看;

走一次之后:slow和fast之间的距离:N - 1

走两次之后:slow和fast之间的距离:N - 2

走三次之后:slow和fast之间的距离:N - 3

……

走N次之后:slow和fast之间的距离就会变为0,这就意味着fast一定会追上slow,最终相遇;

————————————————————————————————————————

在看完这个问题之后,我们再来分析分析fast一次走三步的情况,fast还能追上slow吗?还是如上图所示:

每次走完后slow和fast之间的距离就会减少2,那按照这种现象,我们就需要分成两种情况讨论:

当N为奇数和偶数的时候,我们所要面临的就是两种不一样的情况: 

N为奇数N为偶数
走一次距离差N - 2N - 2
走两次距离差N - 4N - 4

走三次距离差

N - 6N - 6
……………………
走N次距离差34
走N+1次距离差12
走N+2次距离差-10

我们可以发现:当N为偶数的时候,走了若干次后,距离差为0,说明fast能追上slow,那当N为奇数时,我们可以看到,走了若干次后,距离差变成了-1、

这个 -1 是什么意思?

这表明,在fast在走三步的情况下,当他们的距离为N时,走了若干次后,fast有可能会反超slow,跑到slow前面,开始新一轮的追赶,如下图所示:

假设环的长度为C,那么在fast反超slow之后,它们之间的距离就变成了C - 1,这样就会展开新一轮的追赶,对于这新一轮追赶fast是否能追上slow,我们又要分两种情况讨论,也就是C-1分别为奇数和偶数的情况:

C - 1为奇数C - 1为偶数
走一次距离差C - 3

C - 3

走两次距离差C - 5  C - 5
走三次距离差C - 7C - 7
……………………
走N回距离差54
走N + 1回距离差12
走N + 2回距离差-10

我们可以看到,在这新一轮追赶中,如果C - 1是偶数,fast就会在新一轮追赶中追赶上slow,若C-1是奇数,经过若干次追赶后,fast和slow之间的距离又会变成-1,即C - 1,距离差又是一个奇数,陷入死循环;

也就是说,在N为奇数的前提下,当C是偶数,C - 1为奇数时,fast永远都不可能追上slow,会一直错过,陷入死循环;

——————————————————————————————————————————

综上所述:

当slow进环时,fast和slow之间的距离为N,N为奇数,同时环的长度C为偶数时,fast走三步,slow走一步,fast永远都不会追上slow;

这是我们理论分析所得出的结论,我们也在潜意识上默认它的正确性;

但是,事实真的如此吗?

C为偶数,同时N为奇数的情况真的会同时存在吗?

结果其实是否定的,这两种情况事实上不可能同时存在,当然这需要我们进一步的分析,我们可以采用反证法,如下图所示:

 我们设slow在进环时走过的长度为L,环的周长为C,此时fast和slow之间的距离为N

fast在slow进环前早已进环,或许fast在环内已经走了很多圈,我们假设fast在环内已经走了k圈,k可为0,那fast走过的距离即为L + k * C + C - N;

同时fast行进的距离是slow的三倍,所以fast走过的距离也可以表示为3L;

由此得到如下等式:

3L = L + k * C + C - N;

整理可得:

2L = (k + 1)* C - N;

如果按我们所希望的,N是奇数,同时C是偶数,我们就会得到如下关系:

一个偶数和奇数的差不可能会是一个偶数,因此N为奇数,C为偶数的情况是不可能同时成立的;

要么C、N同为奇数,要么同为偶数,要么N为偶数,C为奇数;

——————————————————————————————————

所以,就算fast走3步,slow走一步,最后也会追上的,第一趟无法追上,在第二趟也一定会追上,这个证明题的坑很深,所以我们一定要注意;

至于fast每走四步、五步等情况,其大致思路和每走三步是一样的,只是在一些细节上分析的更加微妙,这需要我们分更多的情况讨论,这里就不在赘述了,我们来进入下一个模块;

4.如何找到成环的结点;

在研究带环链表的时候,我们也需要知道究竟是那个结点成环;

对于这个问题,我们还是回到fast走两步,slow走一步来解决,在这种情况下,slow和fast从头结点开始往后走,最终会在环上的某一个结点相遇;

我们让一个指针从相遇的节点开始走,另一个结点从头结点开始走,它们最终会在成环结点处相遇;

这个结论的证明,其实也很简单,如下图所示:

我们还是借用这张图,当slow和fast相遇后:

假设相遇的位置距离slow的初始位置为D

此时,slow走过的距离:L + C - D

此时,fast走过的距离:L + k * C + C - D

同时,fast走过的距离也为 :2 *(L + C - D)

得到如下等式:

2 * ( L + C - D) = L + k * C + C - D

整理可得:

L = D + k * C

这样就能得出这个结论;当一个指针从相遇点开始走时,走过D距离后,再走k圈,k >= 0,其大小就正好为L,与从头结点开始走的结点相遇;

来看代码实现:

pSLNode CycleSList(pSLNode phead)
{
	pSLNode fast = phead, slow = phead;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
		if (slow == fast)
		{
			pSLNode meet = slow;
			pSLNode cur = phead;
			while (meet != cur)
			{
				meet = meet->next;
				cur = cur->next;
			}
			return meet;
		}
	}

	//没找到
	return NULL;
}

那关于链表的环的问题到这也就结束了,这对于我们思维逻辑的训练有很大的帮助,大家也一定要勤动手来手撕代码,多写才能多记忆,才能有更深的体会;下面给出本次博客所写的代码:

代码:

SList.h:

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <time.h>

typedef int SLDataType;

//定义链表的一个结点
typedef struct SListNode
{
	SLDataType data;
	struct SListNode* next;
}SLNode,* pSLNode;

//申请链表的一个节点
pSLNode BuySListNode(SLDataType x);

//尾插数据
void SListPushBack(pSLNode* pphead, SLDataType x);

//打印链表
void ShowSList(pSLNode phead);

//求链表的长度
int SListLength(pSLNode phead);

//成环
void CreateCycle(pSLNode phead, int len);

//判断链表是否成环
bool IsCycle(pSLNode phead);

//求环节点
pSLNode CycleSList(pSLNode phead);

SList.c:

#define  _CRT_SECURE_NO_WARNINGS 1

#include "SList.h"

pSLNode BuySListNode(SLDataType x)
{
	pSLNode newnode = (pSLNode)malloc(sizeof(SLNode));
	if (newnode == NULL)
	{
		perror("malloc");
		exit(-1);
	}
	newnode->data = x;
	newnode->next = NULL;

	return newnode;
}


void SListPushBack(pSLNode* pphead, SLDataType x)
{
	pSLNode newnode = BuySListNode(x);
	if (*pphead == NULL)
		*pphead = newnode;
	else
	{
		//先找到尾
		pSLNode tail = *pphead;
		while (tail->next)
		{
			tail = tail->next;
		}
		tail->next = newnode;
	}
}


void ShowSList(pSLNode phead)
{
	pSLNode cur = phead;
	while (cur)
	{
		printf("%d->", cur->data);
		cur = cur->next;
	}
	printf("NULL\n");
}


int SListLength(pSLNode phead)
{
	int len = 0;
	pSLNode cur = phead;
	while (cur)
	{
		++len;
		cur = cur->next;
	}

	return len;
}


void CreateCycle(pSLNode phead, int len)
{
	int k = 0 + rand() % (len - 1 - 0 + 1);
	pSLNode cur = phead;
	while (k--)
	{
		cur = cur->next;
	}
	//找尾
	pSLNode tail = phead;
	while (tail->next)
	{
		tail = tail->next;
	}
	tail->next = cur;
}


bool IsCycle(pSLNode phead)
{
	pSLNode slow = phead;
	pSLNode fast = phead;
	while (fast && fast->next)
	{
		//slow一次走一步
		slow = slow->next;
		//fast一次走两步
		fast = fast->next->next;

		if (fast == slow)
		{
			//相遇了
			return true;
		}
	}

	//fast走到空或链表本身就为空
	return false;
}


pSLNode CycleSList(pSLNode phead)
{
	pSLNode fast = phead, slow = phead;
	while (fast && fast->next)
	{
		slow = slow->next;
		fast = fast->next->next;
		if (slow == fast)
		{
			pSLNode meet = slow;
			pSLNode cur = phead;
			while (meet != cur)
			{
				meet = meet->next;
				cur = cur->next;
			}
			return meet;
		}
	}

	//没找到
	return NULL;
}

Test.c:

#define  _CRT_SECURE_NO_WARNINGS 1

#include "SList.h"

void Test1()
{
	pSLNode plist = NULL;
	SListPushBack(&plist, 1);
	SListPushBack(&plist, 2);
	SListPushBack(&plist, 3);
	SListPushBack(&plist, 4);
	SListPushBack(&plist, 5);
	SListPushBack(&plist, 6);
	ShowSList(plist);

}

void TestCreateCycle()
{
	pSLNode plist = NULL;
	int n = 0;
	//输入单链表的值,并以-1结束
	int len = 0;//记录链表的长度
	printf("请输入单链表的值,并以-1结束:>\n");
	do
	{
		scanf("%d", &n);
		if (n != -1)
		{
			SListPushBack(&plist, n);
			++len;
		}
	} while (n != -1);
	ShowSList(plist);

	srand((unsigned int)time(NULL));
	CreateCycle(plist, len);
	printf("成环后的链表为:>\n");
	ShowSList(plist);
}

void TestIsCycle()
{
	pSLNode plist = NULL;
	printf("请输入单链表的值,并以-1结束:>\n");
	int n = 0;
	do
	{
		scanf("%d", &n);
		if (n != -1)
		{
			SListPushBack(&plist, n);
		}
	} while (n != -1);

	int len = SListLength(plist);
	//CreateCycle(plist, len);

	bool ret = IsCycle(plist);
	if (ret == true)
	{
		printf("该链表是带环链表\n");
	}
	else
	{
		printf("该链表不是带环链表\n");
	}
}

int main()
{
	//Test1();
	//TestCreateCycle();
	TestIsCycle();

	return 0;
}

seurat v5更新及样本整合方法 1 Seurat 对象和 Assay 类发生了变化:支持更多种类的检测和数据类型,包括磁盘上的矩阵。引入了分层结构来存储数据,例如原始计数、标准化数据和 z 得分/方差稳定数据。可以使用 $ 访问器或 LayerData 函数来访问数据。现有的 Seurat v4 函数和工作流程仍可在 v5 中使用。2 整合工作流程发生了变化:简化了整合流程,提高了速度和内存效率。整合结果与 v4 工作流程略有不同,但用户仍可在 v5 中运行 v4 整合工作流程。 阅读详情

相关推荐

低成本主从机械臂系统构建:6D位姿数据采集与VLA模型训练实战

本文详细介绍了如何构建低成本主从机械臂系统,实现高精度6D位姿数据采集与VLA模型训练。通过300美元级别的硬件组合,系统达到±1mm位置精度和≤0.5°姿态误差,满足Vision-Language-Action模型的多模态训练需求。文章涵盖硬件选型、数据采集技巧、模型训练实战经验,为机器人研究提供经济高效的解决方案。

r7s8t的博客 266

环形链表详解

环形链表是一种特殊类型的链表数据结构,其最后一个节点的"下一个"指针指向链表中的某个节点,形成一个闭环。换句话说,链表的最后一个节点连接到了链表中的某个中间节点,而不是通常情况下连接到空指针(null)。如图:由于链表最后一个节点的下一个指针没有指向NULL,而是指向前面的某一个节点,所以我们不能再用 “current->next==NULL” 作为判断条件来遍历链表(这样会造成死循环),通常使用快慢指针来控制条件,下面的两个题目都是要借助快慢指针来实现。

2201_75479723的博客 4020

STM32L476低功耗实战:LPTIM精准定时唤醒STOP2模式与系统级功耗优化

本文深入探讨了STM32L476低功耗实战技巧,重点解析了LPTIM精准定时唤醒STOP2模式的配置与优化。通过详细的步骤指南和实战经验分享,帮助开发者实现系统级功耗优化,特别适合电池供电设备开发。文章涵盖LPTIM1定时器配置、STOP2模式进入流程及常见问题排查,助力将整机功耗降至8.2uA级别。

weixin_33686714的博客 435

数据结构-链表里面的环

数据结构--链表里面的环(判断是否有环,环的入口)

菜菜子&的博客 2965

避坑指南:用Adams做滚珠丝杠仿真时90%人会遇到的3个建模错误

本文针对使用Adams进行滚珠丝杠动力学仿真时常见的三大建模错误,提供了详细的避坑指南。重点解析了如何避免因直接导入CAD几何体导致的性能与精度问题,科学设置接触参数以提升计算效率与结果平滑度,以及通过规范的命名与组织管理模型,确保仿真过程高效可靠。

gin88的博客 572

Power Automate实战:用SharePoint REST API批量处理列表数据(附JSON解析技巧)

本文深入探讨了如何利用Power Automate调用SharePoint REST API实现列表数据的批量自动化处理。文章详细解析了API的协同工作原理、高效的数据获取与筛选技巧,并重点分享了JSON数据解析的核心难点与实战解决方案,旨在帮助企业用户构建稳定可靠的数据处理流程,提升运营效率。

coffee的博客 769

带环链表详解

环形链表及其相关问题

m0_62692838的博客 1215

泰山派RK3576开发板部署Qwen3-VL-4B多模态模型实战指南:从模型转换到板端推理全流程

本文提供了在泰山派RK3576开发板上部署阿里Qwen3-VL-4B多模态模型的完整实战指南。详细介绍了从环境准备、模型转换(包括视觉模型转换为.rknn格式和语言模型转换为.rkllm格式)、交叉编译到板端推理的全流程,重点讲解了如何利用RK3576的NPU进行硬件加速,实现高效的边缘AI应用。

weixin_30356433的博客 257

链表的带环问题---数据结构

这里我以 fast 一次走3步,slow 一次走1步为例,来给大家讲解,其他的情况也可以类似分析。上述的链表没有尾部,相对于我们常见的链表而言,他的尾节点的 next 指针指向链表中的任意一个节点,也就在链表中形成了环形结构,下面我们来看一下如何判断链表是否存在带环结构。以上也就解决了我们的链表带环问题,如果还想进一步练习,可以刷一下下面的题目。时的这种情况是不存在的,下面我们来进一步分析 N 与 C 之间的关系。)指针同时指向链表的头结点,快指针每次走两步(但事实并非与我们上述的分析一样,当。

Zjxbxv11的博客 940

使用 CFD 仿真进行阀门性能分析:第一部分

了解如何使用 Ansys Discovery 评估阀门性能,使工程师能够设计出更好的产品。

jkh920184196的博客 3144

LangGraph教程8:LangGraph流式处理

流式处理可显著提升基于LLM应用的响应性。LangGraph支持两种流式模式:values模式返回每一步的完整结果,适合需要完整上下文处理的场景;updates模式仅返回增量变化,适用于实时更新需求。示例代码展示了如何用create_react_agent实现这两种模式,其中values模式完整记录处理流程,updates模式逐步输出结果。通过异步迭代输出流,开发者可以灵活选择适合应用场景的流式处理方式。

Cachel Wood的博客 619

【链表->环形链表】

链表之环形链表,有关环形链表的相关知识

如果需要沟通,可添加微信公众号找我免费答疑 1904

全面指南:PyTorch与ROCm版本兼容性及多版本环境管理

本文详细介绍了在AMD GPU上配置PyTorch开发环境的完整流程,重点解决版本兼容性和多版本ROCm环境管理问题。主要内容包括:1) PyTorch与ROCm版本对应关系查询;2) 四种查看ROCm版本的方法;3) 使用update-alternatives管理多版本ROCm;4) 环境变量配置与冲突解决方案;5) 完整的验证流程和性能测试方法。文章提供了最佳实践建议和故障排除清单,帮助开发者快速搭建稳定高效的深度学习开发环境,充分发挥AMD GPU硬件性能。通过系统化的验证流程确保各组件协同工作,解决

数字人生 606

链表环问题

在实际应用中,快慢指针法(Floyd的循环查找算法)因其高效且不需要额外空间(除了指针变量)而被广泛使用。哈希表法虽然时间复杂度也是O(n),但需要额外的存储空间。双重遍历法的时间复杂度较高,为O(n^2),因此在链表较长时效率较低。标记法则可能不适用于需要保持链表结构不变的场景。

m0_56653160的博客 1153

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

判断单链表是否有环并找到环的入口等问题

判断单链表是否有环并找到环的入口等问题 假设一个单链表有环,他就是下面的这种情况: 我们有下面几个问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 对于这些问题有一种方法就是...

weixin_42078660的博客 7776

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

链表有环问题

链表有环问题

Llinxi的博客 386

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

【链表1】有关链表环的各种问题

==小记== 以前只研究过如何判断一个链表是否有环,结果百度三面的时候SB了,因为关链表环有各种各样的问题 【问题1】如何判断一个链表是否有环 【问题2】如何选择两个指针的步长 【问题3】链表环的起点在哪

mermaidz的专栏 878

链表:链表环问题总结

之前写了篇关于链表的博客,突然想起以前遇到的一些关于链表环问题的情况。所以赶紧百度了一下,现在作一下整理。给定一个单链表,只给出头指针h:1、如何判断是否存在环?2、如何知道环的长度?3、如何找出环的连接点在哪里?4、带环链表的长度是多少?1、如何判断是否存在环?对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fa...

—— 1741

链表的环问题

链表的环问题 如何判断链表中是否有环,若存在环,如何找到入口? 方法一:使用额外的空间 利用一个map记录已经存在的node, 当出现第二次即为存在环也是环的入口。 方法二:不使用额外的空间 先解决是否有环的问题,设置快慢指针,类别是跑步问题,在一个环形跑道上跑快的总会追赶上慢的,那么,如果存在环,快指针总会追上慢指针的。(在链表问题中,使用快慢指针是一个很重要的技巧) 下面是求环的

ustbfym的博客 318

有关链表环的问题

链表的环的问题一般分为三个阶段:判断是否有环,环的长度,环的起点。 1.判断是否有环:利用快慢指针。 两个指针从同一个起点出发,一个走两步,一个走一步。当两个指针相遇时,则证明有环。这个组合应该是最快的了。当提升1倍的速度,必须考虑路程的增加必须少于环长的一半,否则是没有效果的。当环比较大的时候,这是不合适的。 int linkedListCycleLength(ListNode *head

A1031091451的博客 356

单链表有环的几个问题

转自:https://www.cnblogs.com/dancingrain/p/3405197.html 给定一个单链表,判断其中是否有环,已经是一个比较老同时也是比较经典的问题,在网上搜集了一些资料, 然后总结一下大概可以涉及到的问题,以及相应的解法。 首先,关于单链表中的环,一般涉及到一下问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 5.如果存在环,求出环上距离任意一个.

wanlong1215的博客 353

从数学原理剖析链表中的环问题

找题目太麻烦了,为了偷懒,本文中部分前面7个题目引用自以下文章,不过描述方式并不是照抄,是根据自己的理解从数学原理层面进行了说明: https://www.cnblogs.com/yorkyang/p/10876604.html 很多同学在面试时,都遇到过链表中的环问题,本文对于链表环的常见问题给出解答,并对原因进行透彻的分析。 先列一下常见的问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 5.如

suyang001的专栏 470

单向链表环相关问题

目录 一、判断单链表中是否有环 二、求有环单链表的环长 三、求有环单链表的环起点 四、求有环单链表的链表长度 五、代码实现 六、确定两个单向链表是否相交 核心:快慢指针(fast每次2步、slow每次1步) 参考 -1- - 2- 一、判断单链表中是否有环 使用两个指针从头开始扫描链表。 如果存在环,则两指针会相遇;如果不存在环指针fast遇到NUL...

来啦(#^.^#) 399

链表有环的问题

给定一个单链表,判断其中是否有环,已经是一个比较老同时也是比较经典的问题,在网上搜集了一些资料, 然后总结一下大概可以涉及到的问题,以及相应的解法。 首先,关于单链表中的环,一般涉及到一下问题: 1.给一个单链表,判断其中是否有环的存在; 2.如果存在环,找出环的入口点; 3.如果存在环,求出环上节点的个数; 4.如果存在环,求出链表的长度; 5.如果存在环,求出环上...

weixin_30367543的博客 122

判断单链表中是否有环等相关问题

1.如何判断一个链表是否有环? 采用快慢指针的思路,一个指针一次移动一个结点,另一个指针移动两个结点,如果有环,则进入环后,快指针肯定可以追赶上慢指针,这样就会出现两者相等的情况,从而得出有环。 代码实现(例子:Leetcode第141题) /** * Definition for singly-linked list. * struct ListNode { * int val...

Adenson的博客 512
上一篇: 贪吃蛇小游戏C语言全实现
下一篇: 【C++】【算法】高精度加减乘除
鼓浪屿Estelle
博客等级 码龄3年 307粉丝 11原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值