笔试题:如何判断单链表是否存在环

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

1、如何判断是否存在环?

2、如何知道环的长度?

3、如何找出环的连接点在哪里?

4、带环链表的长度是多少?

 

解法:

1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。

2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰撞所走过的操作数就是环的长度s。

3、问题3:有定理:碰撞点p到连接点的距离=头指针到连接点的距离,因此,分别从碰撞点、头指针开始走,相遇的那个点就是连接点。

该定理的证明可参考:http://fayaa.com/tiku/view/7/

4、问题3中已经求出连接点距离头指针的长度,加上问题2中求出的环的长度,二者之和就是带环单链表的长度

 

 

判断是否存在环的程序:

bool IsExitsLoop(slist *head)
{
    slist *slow = head, *fast = head;

    while ( fast && fast->next ) 
    {
        slow = slow->next;
        fast = fast->next->next;
        if ( slow == fast ) break;
    }

    return !(fast == NULL || fast->next == NULL);
}

 

 

寻找环连接点(入口点)的程序:

slist* FindLoopPort(slist *head)
{
    slist *slow = head, *fast = head;

    while ( fast && fast->next ) 
    {
        slow = slow->next;
        fast = fast->next->next;
        if ( slow == fast ) break;
    }

    if (fast == NULL || fast->next == NULL)
        return NULL;

    slow = head;
    while (slow != fast)
    {
         slow = slow->next;
         fast = fast->next;
    }

    return slow;
}

 

完整演示程序:

#include "stdio.h"
#include "stdlib.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;

Status initList(Node** L){
	
	*L = (Node*)malloc(sizeof(Node));
	if(!(*L)){
		return ERROR;
	}
	
	(*L)->next = NULL;
	return OK;
}


int listLength(Node* L){
	
	int i = 0;
	Node* p = L->next;
	while(p){
		i++;
		p = p->next;
	}
	return i;
}

// Non-Chain
void createListHead(Node** L, int n){
	
	Node* p;
	int i;
	
	srand(time(0));
	
	*L = (Node*)malloc(sizeof(Node));
	(*L)->next = NULL;
	
	for(i=0; i<n; i++){
		p = (Node*)malloc(sizeof(Node));
		// p->data = rand()%100+1;
		p->data = i+1;
		p->next = (*L)->next;
		(*L)->next = p;
	}
}

// Chain
void createListTail(Node** L, int n){
	
	Node* p, *r;
	int i;
	
	srand(time(0));
	*L = (Node*)malloc(sizeof(Node));
	r = *L;
	
	for(i=0; i<n; i++){
		p = (Node*)malloc(sizeof(Node));
		// p->data = rand()%100+1;
		p->data = i+1;
		r->next = p;
		r = p;
	}
	
	// 把尾节点与第二个节点连接起来
	r->next = (*L)->next->next;
}

// 用两个指针cur1,cur2, cur1每次前进一个pos,cur2每次重头前进直到和cur1指向相同的节点,
// 再比较两者经过的步数是否相等
int hasLoop1(Node* L){
	
	Node* cur1 = L;
	int pos1 = 0;
	
	while(cur1){
		Node* cur2 = L;
		int pos2 = 0;
		while(cur2){
			if(cur2 == cur1){
				if(pos1 == pos2){
					break;
				}
				else{
					printf("Chain is in the %d place\n\n", pos2);
					return 1;
				}
			}
			cur2 = cur2->next;
			pos2++;
		}
		cur1 = cur1->next;
		pos1++;
	}
	
	return 0;
}

// 快慢指针,如果相等则说明有环
int hasLoop2(Node* L){
	
	int step1 = 1;
	int step2 = 2;
	Node* p = L;
	Node* q = L;
	
	while(p!=NULL && q!=NULL && q->next!=NULL){
		p = p->next;
		q = q->next->next;
		
		printf("p:%d, q:%d \n", p->data, q->data);
		
		// 找到相碰点
		if(p == q){
			return 1;
		}
	}
	
	return 0;
}

// 寻找环连接点(入口点)
Node* findLoopEntry(Node* L){
	
	Node* slow = L, *fast=L;
	
	while(fast && slow && fast->next){
		slow = slow->next;
		fast = fast->next->next;
		
		// 找到相碰点
		if(slow == fast){
			printf("Collision point value is %d\n", slow->data);
			break;
		}
	}
	
	if(fast==NULL || fast->next==NULL){
		return NULL;
	}
	
	// 碰撞点p到连接点的距离=头指针到连接点的距离
	slow = L;
	while(slow != fast){
		slow = slow->next;
		fast = fast->next;
	}
	
	return slow;
}



int main(){
	
	Node* L;
	Status i;
	char opp;
	ElemType e;
	int find;
	int tmp;
	
	i = initList(&L);
	printf("After initialization, listLength(L)=%d\n", listLength(L));
	
	printf("\n1.Create Chain Linked list(Tail Insert) \n2.Create Non-Chain Linked List(Head Insert) \n3.Judge if a chain exists \n0.Exit\n\n");
	
	while(opp != '0'){
		scanf("%c", &opp);
		switch(opp){
			case '1':
				createListTail(&L, 10);
				printf("Create Chain LinkedList L(Tail Insert) OK\n");
				printf("\n");
				break;
			
			case '2':
				createListHead(&L, 10);
				printf("Create Non-Chain Linked List(Head Insert) OK\n");
				printf("\n");
				break;
				
			case '3':
				printf("Solution 1: \n\n");
				if(hasLoop1(L)){
					printf("Summary: Chain exists\n\n");
				}
				else{
					printf("Summary: No Chain\n\n");
				}
				
				printf("---------------------------\n\n");
				
				printf("Solution 2: \n\n");
				if(hasLoop2(L)){
					printf("Summary: Chain exists\n\n");
					Node* entry = findLoopEntry(L);
					printf("Entry value is: %d\n", entry->data);
				}
				else{
					printf("Summary: No Chain\n\n");
				}
		}
	}
}

 

LangGraph 中 Human-in-the-loop 摘要:本文探讨了在自主AI Agent系统中实现"人工介入关键节点"(HIL)的技术方案,主要基于LangGraph框架构建。针对Agent可能执行高风险操作(如删除数据库)的问题,提出通过断点机制在关键节点暂停流程,实现人工审批后再继续执行。具体实现包括:(1)使用checkpointer组件持久化状态;(2)通过interrupt_before/after参数设置断点;(3)支持三种交互模式:批准、编辑和输入。文章还提供了代码示例,展示如何在不同场景(如工具调用)中动态触发人工审核机 阅读详情

相关推荐

LoRa项目实战:手把手教你为ESP32选配和焊接天线(从PCB到信号测试)

本文详细介绍了为ESP32选配和焊接LoRa天线的全流程,包括天线选型、PCB布局设计、焊接工艺及信号测试。重点解析了PCB板载天线、导线天线和陶瓷贴片天线的适用场景与性能特点,并提供专业的焊接技巧和信号测试方案,帮助开发者优化LoRa模块的无线通信性能。

weixin_30470643的博客 393

单链表:判断链表中是否有环

判断链表中是否有环 题目:         判断一个链表中是否有环。 示例:         该链表的环是由 4 5 6 7 8这几个节点构成。 思路:         我们可以类比操场上的你追我赶的情形。让A先跑,B后跑,且B的速度比A快,那么总有一个时间点,B会追上A

Colorful_X的博客 406

PE启动盘结合360杀毒离线版:深度清除顽固病毒实战指南

在系统安全维护领域,离线查杀是一种在独立于宿主操作系统的环境下进行病毒扫描和清除的核心技术。其原理是通过一个预启动环境(如PE)加载杀毒软件,从而绕过可能已被感染或受保护的系统核心,直接访问和扫描磁盘文件。这项技术的核心价值在于能够彻底处理那些在正常系统运行时难以清除的深度隐藏病毒、Rootkit和驱动级木马。典型的应用场景包括应对勒索软件、顽固感染型病毒以及系统启动项被劫持等情况。本文以“PE启动盘”和“360杀毒离线版”这一经典组合为例,详细解析了从工具选型、环境部署到深度查杀策略的全流程,为系统维护人

weixin_29741447的博客 408

三、线性表——链表

三、链表 1.快慢指针 1)如何判断单链表是否存在环 ? 问题描述:给定一个单链表L,L为头指针,判断该链表内是否局部存在环? 方法: 快慢指针,快指针的速度为慢指针的2倍,若快慢指针相遇则有环。 #include<iostream> using namespace std; typedef struct LNode //定义单链表 { int data; struct LNode *next; }LNode, *LinkList; void List_TailInsert(LinkL

as_your_heart的博客 583

卫星通信链路预算实战:从EIRP到Eb/N0的完整计算指南(含Excel模板)

本文提供了一份卫星通信链路预算的实战指南,详细解析了从EIRP到Eb/N0的完整计算流程。文章重点对比了C波段与Ku波段在应对降雨衰减等动态因素时的不同策略,并分享了包含核心公式的Excel模板,帮助工程师将理论转化为可执行的系统设计依据。

weixin_29230773的博客 534

保姆级教程:用BMS的HVIL检测电路,手把手教你排查高压互锁故障(附PWM/直流源方案对比)

本文详细解析了BMS中的HVIL检测电路,通过对比直流源与PWM两种方案,提供了一套系统化的高压互锁故障诊断流程。从电路原理到实战技巧,帮助维修人员精准定位故障根源,提升电动汽车高压系统的安全性和可靠性。

weixin_29300241的博客 390

算法面试题:如何判断单链表中是否存在环

题目分析 一道算法面试题:判断单链表是否存在环。 我们知道单链表中结点都是一个结点指向下一个结点这样一个一个链接起来的,直到尾结点的指针域没有指向,单链表就到此结束了。 这里存在环的意思就是,尾结点的指针域并为空,而是指向此单链表的其他结点,这样就形成环了,这样遍历单链表就死循环了因为破坏了结束条件。 前面我们算法面试题 快速找到单链表中间节点 所用的快慢指针,同样可以用来判断是否存在环,

重庆李四 1万+

blenderproc 制作位姿估计数据集

blenderproc 制作位姿估计数据集 准备工作 1.首先需要去下载blenderproc的源码blenderproc,按照作者的readme文件进行编译。 2.其次需要下载bop_toolkit源码,链接如下bop_toolkit 3.说明:blenderproc主要用来生成数据,包括depth,rgb,位姿标签文件(scene_gt.json),bop_toolkit主要用来生成mask和mask_visib,scene_gt_info.json,用于判断物体的可见区域比例,如果遮挡太多考虑去掉。做

qq_43814359的博客 5697

面试题 单链表中判断是否有环以及得出环的入口点

参考链接:单链表中判断是否有环以及得出环的入口点(简单易懂) 1.       判断单链表是否有环 这是很多公司入门级的面试笔试题。单链表由于每个结点只有一个next指针指向下一个结点,不存在其他指针,所以一旦进入环里,就再也出不去了。类似于下图(像一个烤盘)          那么怎么样判断单链表是否有环呢?方法很简单,把环看作操场,两位选手在操场上赛跑,一个速度快,一个速度慢,如果他...

qq_29762941的博客 357

Modbus协议全家桶(C#纯原生完整版):ModbusRTU + ModbusTCP + ModbusASCII 协议规范+完整封装+工业级实战

你已经掌握了C#串口/网口原生核心API和工业通信协议本质,而今天的主角Modbus协议,是工业通信领域绝对的王者、通用的标准、入门的必修课,没有之一。凡是做工业通信开发,必会Modbus协议;市面上99%的工业设备(PLC、变频器、温控仪、传感器、流量计、扫码枪)都原生支持Modbus协议。Modbus协议不是单一协议,而是一个「协议家族」,我们常说的就是这个家族的三大核心成员,也是工业现场的全部Modbus应用形态。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 562

基于STM32H5的循环GPDMA链表使用

STM32H503的GPDMA链表模式可实现灵活的数据传输。相比传统DMA直接编程方式,链表模式通过配置多个节点实现分散数据传输,支持循环链表功能。示例展示了如何使用GPDMA链表实现UART1循环发送数据:配置两个DMA节点分别指向不同发送缓冲区,构建循环链表并绑定到DMA通道。关键点包括:清空链表结构体、正确设置循环模式、检查节点配置。此方法提高了DMA使用的灵活性,适用于需要交替传输多段数据的场景。

kevin1499的博客 451

笔试面试题目:判断单链表是否有环

之前在U公司的笔试中,碰到这样一个问题: 判断单链表是否有环。 首先来看这样一个常识:现实中的环路与单链表的环路,有什么不同呢? 显然:现实中的环路,可以有两个方向,要么循环,要么逃出。然而,在单链表中,指针next只可能有一个指向,所以环路链表必定永远循环,没有出口。如下图所示: 回到问题本身,怎么判断单链表是否有环呢? 算法1:标记法 最容易想到的肯定是标...

认知 行动 坚持 2233

如何成为一名高级数字 IC 设计工程师(6-7)数字 IC 验证篇:DEBUG 技巧

不懂验证的设计不是好的设计;UVM 验证思维是指导缜密的芯片设计的导师;推荐书籍《芯片验证漫游指南》。

新芯设计的博客 1605

判断单链表是否有环的java实现

无论面试还是笔试经常会考这样一道题:怎么判断一个单链表是否存在环? java实现代码如下:package Demo1; public class LinkedLoop { //内部静态类定义结点类 static class Node{ int val; Node next; public Node(int val){ this.val = val; } } //判

njr465167967的博客 7217

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

笔试题:判断一个单链表是否有环,如果有,找出环的起始位置

问题:判断一个单链表是否有环,如果有,找出环的起始位置。分析:是否有环方法一:我们可以从单链表Head开始,每遍历一个,就把那个node放在hashset里,走到下一个的时候,把该node放在hashset里查找,如果有相同的,就表示有环,如果走到单链表最后一个node,在hashset里都没有重复的node,就表示没有环。 这种方法需要O(n)的空间和时间。方法二:设置两个指针指向单链表的hea...

LotusYu_blog 3733

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

如何判断单链表是否存在环

给定一个单链表,只给出头指针h: 1、如何判断是否存在环? 2、如何知道环的长度? 3、如何找出环的连接点在哪里? 4、带环链表的长度是多少?解法: 1、对于问题1,使用追赶的方法,设定两个指针slow、fast,从头指针开始,每次分别前进1步、2步。如存在环,则两者相遇;如不存在环,fast遇到NULL退出。 2、对于问题2,记录下问题1的碰撞点p,slow、fast从该点开始,再次碰

稻草人技术博客 489

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

单链表笔试题(是否相交,求交点;是否有环,求入环点)C++

单链表笔试题(是否相交,求交点;是否有环,求入环点)C++ 1. 判断两个单链表是否相交,若相交求交点。 2. 判断单链表是否有环,若存在环 则返回入环点。

m0_56194716的博客 371

[2014校招笔试]判断单链表是否有环?

某互联网企业的笔试题:判断单链表是否有环?如果有环,如何在O(N)的时间复杂度和O(1)的空间复杂度得到这个环的入口点? 问题1:如何判断有环呢? 这个方法可能不只一种,但是在网上看到的那个类似于两个人跑步的解法最容易让人接受。两个人跑步,同时跑,但一个人在跑的快,一个人跑的慢,如果他们在一个环形操场上跑的话,肯定他们要不只一次的相遇。判断环也是这个原理,两个指针p和q,一开始p和q...

A5656665656556的博客 174

c语言 判断链表之中是否有环,判断单链表中是否存在环(网上说的笔试题)

2015-10-06 06:30:02阅读( 83 )#include “stdafx.h”typedef char eleType;// 定义链表中的数据类型typedef struct listnode {// 定义单链表结构eleType data;struct listnode *next;}node;node *create(int n) {// 创建单链表,n为...

weixin_39748858的博客 254

java 判断链表有环_java实现单链表中是否有环的方法详解

这是一道微软经典笔试题,就是两个指针h1,h2都从头开始遍历单链表,h1每次向前走1步,h2每次向前走2步,如果h2碰到了NULL,说明环不存在;如果h2碰到本应在身后的h1说明环存在(也就是发生了套圈)。如果环不存在,一定是h2先碰到NULL:如果环存在,h2与h1一定会相遇,而且相遇的点在环内:h2比h1遍历的速度快,一定不会在开始的那段非环的链表部分相遇,所以当h1,h2都进入环后,h2每次...

weixin_32375369的博客 253

笔试题----链表及链表环

宗旨就是,弄两个指针来解决单链表和链表环的问题..... 先定义链表里的每个元素Node: class Node{ public int value; public Node next; public Node(int value){ this.value=value; } } 1、单链表相关问题 1.1、找出单链表的倒数第K个元素 定义两个指针p,q,  p先走k步后...

ZHUXIREN的博客 279

数据结构之链表面试题汇总(三)判断单链表是否有环、取出环的起始点、得到有环链表中环的长度

title: 数据结构之链表面试题汇总(三)判断单链表是否有环、取出环的起始点、得到有环链表中环的长度 date: 2016-08-18 9:14:00 categories: 数据结构版权声明:本站采用开放的[知识共享署名-非商业性使用-相同方式共享 许可协议]进行许可所有文章出现的代码,将会出现在我的github中,名字可以根据类全名来找,我在github中的文件夹也会加目录备注。判断单链表

670

题目:①判断一个单向链表是否有环,如果有环则找到环的入口节点。 ②判断两个单向链表是否相交,如果相交则找到交点节点。

淘宝的技术笔试题量不大,但是时间也很短(一个小时),基础题的难度还可以,后面的算法编程题就有点难度了,除非是之前做过类似的题目,否则在考场上用极其有限的时间很难做出来。下面和大家分享一道淘宝的编程题。   题目:①判断一个单向链表是否有环,如果有环则找到环的入口节点。           ②判断两个单向链表是否相交,如果相交则找到交点节点。 算法思想:①用两个指针p

jfkidear的专栏 1653
上一篇: 64位win7使用debug的方法
下一篇: Win7 64位安装VS2010出现错误failed for component Microsoft Visual Studio 2010 64bit Prer
chiiis
博客等级 码龄14年 422粉丝 429原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值