就如数字6一样的单链表结构,如何检测是否有6下部的○呢,并且求交叉点位置

思路

  1. 使用快慢指针(一个一次走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 步

  2. 由上可以使快慢指针第一次到达相遇点时,使慢指针回到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,测试结果均正确!

数据结构--链表--单链表中环的检测,环的入口,环的长度的计算相关推荐

  1. 数据结构:单链表中在P结点前插入S结点

    标题:数据结构:单链表中在P结点前插入S结点 在数据结构的习题中偶然看到了一个题目 已知在单链表中P不是首元结点也不是尾元结点,在P结点前插入S结点 #include<stdio.h> # ...

  2. 数据结构之单链表 python实现

    链表是线性表的链式存取的数据结构,是一种链式存取的数据结构,是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的.链表由一系列结点(链表中每一个元素称为结点 ...

  3. 数据结构上机-尾、头插法建立单链表-单链表遍历C语言完整代码实现

    点击此处跳转视频链接:数据结构上机-尾.头插法建立单链表-单链表遍历C语言完整代码实现

  4. 基本的数据结构:单链表(Singly Linked List)

    一.基本的数据结构:单链表(Singly Linked List) 什么是单链表? 下面是百度百科给出的官方解释: 单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素.链表 ...

  5. 数据结构之单链表的增删查改等操作画图详解

    单链表 文章目录 单链表 链表的概念及其结构 概念 结构 链表的实现 开辟一个新结点 链表的销毁 打印链表 单链表的尾插 单链表的头插 单链表的头删 单链表的尾删 找到单链表中的一个结点 在pos位置 ...

  6. 【数据结构】单链表和双向循环链表

    文章目录 单链表 链表的概念及结构 链表的分类 链表的实现 动态申请一个节点 创建链表 单链表打印 单链表尾插 单链表尾删 单链表头插 单链表头删 单链表的查找 单链表在pos位置之后插入x 单链表删 ...

  7. 【数据结构】——单链表超详细介绍(独家介绍,小白必看!!!)

    被滑走别滑走,我这一万字的文章,写的真的很痛苦的,希望能得到一点点支持!!! 重点内容和易错点都用彩笔标注了,干货满满,耐心看完,我真的真的有在认真更新o(╥﹏╥)o 上一篇文章介绍完顺序表后,我们就 ...

  8. Java数据结构——用单链表编写一个简易通讯录

    Java数据结构--用单链表编写一个简易通讯录 1.定义线性表的抽象数据类型(接口) 2.定义单链表的结点Node类 3.定义数据域中的联系人Person类 4.编写顺序表(类) 5.编写测试程序(m ...

  9. 重温一遍数据结构之单链表(golang版)

    说明 上一篇说的是线性表中的顺序存储结构,他的读取复杂度虽然是o(1),但是它的缺点也很明显,插入和删除需要移动很多元素,而且需要分配一块连续的内存区域 线性表之单链表 单链表在一定程度上解决了一部分 ...

  10. 数据结构之单链表超详细

    目录 单链表介绍和内存布局 单链表的应用实例 单链表的创建和和遍历分析 单链表的创建和和遍历代码 单链表按顺序插入节点 代码实现 单链表结点的修改 删除结点 经典面试题 求单链表的结点个数 查找单链表 ...

最新文章

  1. 前端也要学系列:设计模式之装饰者模式
  2. 为什么要选择Apache Pulsar:IO隔离
  3. SAP BW数据源增强管理
  4. 【图论】Tarjan 缩点
  5. 作为软件设计师的2013年终总结
  6. 利用Skywalking-netcore监控你的应用性能
  7. 【第6章 循环】while语句
  8. 用户体验设计答疑对话(半吊子和纯外行
  9. 硬件加速 | 基于FPGA的深度学习CNN加速器设计(论文复现)
  10. CERC2017 F-Faulty Factorial【数论】
  11. android仿百度新闻,【Android】最新主流新闻app功能实现。仿网易,搜狐等新闻客户端实现展示...
  12. matlab地震振幅属性分析,洛马普列塔地震分析 - MATLAB Simulink Example - MathWorks 中国...
  13. Shiro 第十七章 OAuth2集成
  14. Chrome技巧-如何精准搜索
  15. 游戏抽奖界面html,基于JavaScript实现幸运抽奖页面
  16. 秒表Stopwatch的使用
  17. windows远程桌面,停留在“请稍后”页面
  18. HDU 3277 Marriage Match III(并查集+二分+最大流)
  19. /与./和../的含义
  20. 准备工作—PPT配色篇

热门文章

  1. linux 双mipi摄像头,VS-RK3399 在linux系统下面调试Mipi camera接口介绍
  2. smart700iev3 程序下载设置_分享一款Aira2下载工具
  3. 驱动的定义、分类、安全性
  4. A - Character Encoding HDU - 6397 - 方程整数解-容斥原理
  5. 11月16日 个人战立会议内容报告
  6. Flow monitoring in Software-Defined Networks
  7. Cadence PCB SI
  8. 随感 -- 2013/08/16
  9. js在类的方法中访问自己的属性
  10. 如何将两个DateTimePicker的日期和时间组合成一个值