数据结构--链表--单链表中环的检测,环的入口,环的长度的计算
就如数字6一样的单链表结构,如何检测是否有6下部的○呢,并且求交叉点位置
思路
使用快慢指针(一个一次走2步,一个走1步),若快慢指针第一次相遇,则有环
慢指针路程 s=a+bs = a+bs=a+b
快指针路程 2s=a+b+n∗R2s = a+b+n*R2s=a+b+n∗R
s=n∗Rs = n*Rs=n∗R
链表的长度 L=a+b+c=n∗R+cL = a+b+c = n*R+cL=a+b+c=n∗R+c
又 L=a+RL = a + RL=a+R
则 n∗R+c=a+R⇒(n−1)∗R+c=an*R+c = a+R \Rightarrow (n-1)*R+c = an∗R+c=a+R⇒(n−1)∗R+c=a
意味着从head
开始走到入口 aaa 步 == 从第一次相遇点走 n−1n-1n−1 圈 + 再走 ccc 步由上可以使快慢指针第一次到达相遇点时,使慢指针回到head,快指针仍在相遇点,然后两人步伐一致,最后会在入口相见。
C++代码实现:
完整代码见:https://github.com/hitskyer/course/tree/master/dataAlgorithm/chenmingming/linkedList
类实现函数
bool SingleList::hasLoop()
{bool loop = false;ListNode fast = m_pHead, slow = m_pHead;ListNode posMeet = m_pHead, ringEntrance = m_pHead;//环的可能的入口应初始化成headif(m_pHead == NULL){loop = false;std::cout << "list has no loop!" << std::endl;}else{while(fast && fast->pNext){fast = fast->pNext->pNext;slow = slow->pNext;if(fast == slow){loop = true;posMeet = fast; //第一次相遇的地方break;}}slow = m_pHead; //接着让慢指针回到表头(这里是关键),继续一起同步前行,第二次相遇的地方为环的入口while(slow != fast){slow = slow->pNext;fast = fast->pNext;if(fast == slow)ringEntrance = fast;}size_t lenOf_headToEntrance = howManyNode(m_pHead,ringEntrance);size_t ringLen_1 = howManyNode(ringEntrance->pNext, ringEntrance);std::cout << "len of head to ring entrance is " << lenOf_headToEntrance << std::endl;std::cout << "entrance Node is " << ringEntrance->data << std::endl;std::cout << "len of ring is " << ringLen_1 + 1 << std::endl;std::cout << "len of List is " << lenOf_headToEntrance + ringLen_1 + 1 << std::endl;}return loop;
}size_t SingleList::howManyNode(ListNode ps, ListNode pe) //计算两个指针之间有多少个节点(不包含第二个参数处的节点)
{size_t count = 0;while(ps != pe){ps = ps->pNext;++count;}return count;
}
singleListIsLoop.cpp主函数
//
// Created by mingm on 2019/3/24.
//检查单链表中是否存在环,求环的长度,链表长度,及环的入口
#include <iostream>
#include <time.h>
#include <cstdlib>
#include "./homework/singleList.cpp"
using namespace std;
int main()
{srand((unsigned)time(NULL)); //用时间随机数种子size_t len = 10; //测试链表最大长度for(size_t j = 1; j < len; ++j){SingleList intList;for(size_t i = 0; i < j; ++i){intList.AddTail(rand()%100); //添加随机数到链表}cout << "no loop list: " << endl;intList.PrintList(); //排序前链表打印size_t n = rand()%(intList.GetLength()); //0-链表减1的随机数ListNode randNode = intList.GetHeadNode();for(size_t i = 0; i != n; ++i){randNode = randNode->pNext; //链表的一个随机节点}ListNode originTail = intList.GetTailNode();originTail->pNext = randNode; //尾节点接入链表中的随机位置形成环intList.hasLoop(); //调用环检测函数originTail->pNext = NULL; //断开环,让链表能够按照单链表析构函数析构!!!!!!!std::cout << "getListLength() is " << intList.GetLength() << std::endl;std::cout << "-----------------------------------------" << std::endl;}return 0;
}
Valgrind检测结果
从链表长度1开始测试到9,测试结果均正确!
数据结构--链表--单链表中环的检测,环的入口,环的长度的计算相关推荐
- 数据结构:单链表中在P结点前插入S结点
标题:数据结构:单链表中在P结点前插入S结点 在数据结构的习题中偶然看到了一个题目 已知在单链表中P不是首元结点也不是尾元结点,在P结点前插入S结点 #include<stdio.h> # ...
- 数据结构之单链表 python实现
链表是线性表的链式存取的数据结构,是一种链式存取的数据结构,是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点 ...
- 数据结构上机-尾、头插法建立单链表-单链表遍历C语言完整代码实现
点击此处跳转视频链接:数据结构上机-尾.头插法建立单链表-单链表遍历C语言完整代码实现
- 基本的数据结构:单链表(Singly Linked List)
一.基本的数据结构:单链表(Singly Linked List) 什么是单链表? 下面是百度百科给出的官方解释: 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表 ...
- 数据结构之单链表的增删查改等操作画图详解
单链表 文章目录 单链表 链表的概念及其结构 概念 结构 链表的实现 开辟一个新结点 链表的销毁 打印链表 单链表的尾插 单链表的头插 单链表的头删 单链表的尾删 找到单链表中的一个结点 在pos位置 ...
- 【数据结构】单链表和双向循环链表
文章目录 单链表 链表的概念及结构 链表的分类 链表的实现 动态申请一个节点 创建链表 单链表打印 单链表尾插 单链表尾删 单链表头插 单链表头删 单链表的查找 单链表在pos位置之后插入x 单链表删 ...
- 【数据结构】——单链表超详细介绍(独家介绍,小白必看!!!)
被滑走别滑走,我这一万字的文章,写的真的很痛苦的,希望能得到一点点支持!!! 重点内容和易错点都用彩笔标注了,干货满满,耐心看完,我真的真的有在认真更新o(╥﹏╥)o 上一篇文章介绍完顺序表后,我们就 ...
- Java数据结构——用单链表编写一个简易通讯录
Java数据结构--用单链表编写一个简易通讯录 1.定义线性表的抽象数据类型(接口) 2.定义单链表的结点Node类 3.定义数据域中的联系人Person类 4.编写顺序表(类) 5.编写测试程序(m ...
- 重温一遍数据结构之单链表(golang版)
说明 上一篇说的是线性表中的顺序存储结构,他的读取复杂度虽然是o(1),但是它的缺点也很明显,插入和删除需要移动很多元素,而且需要分配一块连续的内存区域 线性表之单链表 单链表在一定程度上解决了一部分 ...
- 数据结构之单链表超详细
目录 单链表介绍和内存布局 单链表的应用实例 单链表的创建和和遍历分析 单链表的创建和和遍历代码 单链表按顺序插入节点 代码实现 单链表结点的修改 删除结点 经典面试题 求单链表的结点个数 查找单链表 ...
最新文章
- 前端也要学系列:设计模式之装饰者模式
- 为什么要选择Apache Pulsar:IO隔离
- SAP BW数据源增强管理
- 【图论】Tarjan 缩点
- 作为软件设计师的2013年终总结
- 利用Skywalking-netcore监控你的应用性能
- 【第6章 循环】while语句
- 用户体验设计答疑对话(半吊子和纯外行
- 硬件加速 | 基于FPGA的深度学习CNN加速器设计(论文复现)
- CERC2017 F-Faulty Factorial【数论】
- android仿百度新闻,【Android】最新主流新闻app功能实现。仿网易,搜狐等新闻客户端实现展示...
- matlab地震振幅属性分析,洛马普列塔地震分析
- MATLAB Simulink Example
- MathWorks 中国...
- Shiro 第十七章 OAuth2集成
- Chrome技巧-如何精准搜索
- 游戏抽奖界面html,基于JavaScript实现幸运抽奖页面
- 秒表Stopwatch的使用
- windows远程桌面,停留在“请稍后”页面
- HDU 3277 Marriage Match III(并查集+二分+最大流)
- /与./和../的含义
- 准备工作—PPT配色篇
热门文章
- linux 双mipi摄像头,VS-RK3399 在linux系统下面调试Mipi camera接口介绍
- smart700iev3 程序下载设置_分享一款Aira2下载工具
- 驱动的定义、分类、安全性
- A - Character Encoding HDU - 6397 - 方程整数解-容斥原理
- 11月16日 个人战立会议内容报告
- Flow monitoring in Software-Defined Networks
- Cadence PCB SI
- 随感 -- 2013/08/16
- js在类的方法中访问自己的属性
- 如何将两个DateTimePicker的日期和时间组合成一个值