若链表中存在环,找出其中的环所在的节点,否则,返回NULL

在没有C++ set容器的优势前提下,我们对这样的环型的寻找以及定位可以利用快慢指针来实现。
有环的存在,类似与操场跑圈,必然存在快慢之分。有了快慢,就一定会有交点。反之,有了交点,就一定存在环。

实现过程如下:

  1. slow指针移动一次,fast指针移动两次,当fast指针和slow指针相等时保留相等时的节点
  2. 根据运算,从相等时的节点和头节点以相同的速度运算,当两者相等时即为环的起始节点


算法实现如下:

Data *get_circle_list(Data *head) {Data *fast;Data *slow;fast  = head;slow = head;Data *meet = NULL;/*快速和慢速指针一起移动*/while (fast) {fast = fast -> next;slow = slow -> next;if (!fast) {//当快速指针为空时,即不存在环型节点return NULL;}//否则快速指针继续移动fast = fast -> next;if(fast == slow) {meet = fast;break;}}/*如果没有找到相遇的节点,那么即不存在环型*/if(meet == NULL) {return NULL;} else {while (!(head == meet)) {head = head -> next;meet = meet -> next;}return head;}return NULL;
}

源代码测试如下:

#include <stdio.h>
#include <stdlib.h>typedef struct link_list {int data;struct link_list *next;
}Data;void print_list(Data *head) {while (head) {printf("%d ",head->data);head = head -> next;}printf("\n");
}Data *insert_head(Data *head, int n) {head = (Data *)malloc (sizeof(Data));head -> next = NULL;int data;while(n --) {Data *p = (Data *)malloc(sizeof(Data));scanf("%d",&data);p -> data = data;p -> next = head -> next;head -> next = p;}return head;
}Data *insert_tail(Data *head, int n) {head = (Data *)malloc(sizeof(Data));head -> next = NULL;Data *r = head;int data;while(n--) {Data *p = (Data *)malloc(sizeof(Data));scanf("%d", &data);p -> data = data;r -> next = p;r = p;p -> next = NULL;}return head;
}Data *get_circle_list(Data *head) {Data *fast;Data *slow;fast  = head;slow = head;Data *meet = NULL;while (fast) {fast = fast -> next;slow = slow -> next;if (!fast) {return NULL;}fast = fast -> next;if(fast == slow) {meet = fast;break;}}if(meet == NULL) {return NULL;} else {while (!(head == meet)) {head = head -> next;meet = meet -> next;}return head;}
}int main() {/*构造环形测试用例*/Data a1,a2,a3,a4,a5,a6,a7;a1.data = 1;a2.data = 2;a3.data = 3;a4.data = 4;a5.data = 5;a6.data = 6;a7.data = 7;a1.next = &a2;a2.next = &a3;a3.next = &a4;a4.next = &a5;a5.next = &a6;a6.next = &a7;/*构造环形,这里很明显环形的起点为5节点*/a7.next = &a5;printf("get circle node \n");Data *result = get_circle_list(&a1);printf("get circle node is %d\n",result -> data);return 0;
}

输出如下:

get circle node
get circle node is 5

C语言单链表求环,并返回环的起始节点相关推荐

  1. 带环单链表求入口节点原理

    单链表求环长点击打开链接

  2. C语言的单链表求交点

    单链表求交点,问题如下: 使用o(1)的空间复杂度,求两个链表相交的时候的交点,这个思想就类似于使用o(1)的空间复杂度和o(n)的时间复杂度来求链表的第k个节点. 过程如下: 获取两个链表的长度 将 ...

  3. C语言单链表基本操作总结

    C语言单链表基本操作     本文是参考他人实现的C语言单链表,对多篇博文整理的结果,仅作为学习笔记.文末有参考出处. 1.单链表定义 链表是通过一组任意的存储单元来存储线性表中的数据元素,这些存储单 ...

  4. C语言一趟冒泡交换最小值,C语言单链表冒泡排序为啥以下代码实现不了?

    struct node *sort(struct node *head)/*排序*/ { struct node *p,*q; struct node *temp; for(p=head;p!=NUL ...

  5. C语言单链表,能直接运行的代码!

    C语言单链表,实现增删改查 不废话 直接上代码,COPY就能运行 #include <stdio.h> #include <stdlib.h> /** *定义数据元素 */ t ...

  6. 链式存储【C语言单链表】

    文章目录 单链表 单链表的结构 需要的头文件 申请节点 单链表尾插 单链表头插 单链表尾删 单链表头删 单链表查找 单链表在(pos之前/pos之后)插入数据 单链表删除(pos/pos之后)数据 单 ...

  7. C语言单链表代码实现

    C语言单链表代码实现 一.头文件.常量以及自定义数据结构 #include<stdio.h> #include<malloc.h> #include<stdlib.h&g ...

  8. c语言单链表倒置(附原理讲解)

    c语言单链表倒置 今天博主,讲一个单链表倒置的例子,事实上 话不多说,我们直接上代码,待会会给大家讲解倒置算法实现原理 #include<stdio.h> #include<stdl ...

  9. C语言 单链表通讯录基础版实现,保证看完都直呼easy

    C语言 单链表实现通讯录基础版,保证看完都大呼简单! --------------------------------- 首先在写通讯录之前,必须明确我们的需求: 因为是基础版,我在这里暂时只实现以下 ...

最新文章

  1. 离人类更近一步!DeepMind最新Nature论文:AI会“回忆”,掌握调取记忆新姿势
  2. python3 字符串截取
  3. 【深度学习】你有哪些深度学习(RNN、CNN)调参的经验?
  4. 点击弹出窗口外任意地方关闭弹出窗口
  5. 大学计算机基础教程模拟选择题,【浙江大学】大学计算机基础教程——习题与参考答案...
  6. 小米6android版本更新,钉子户小米6的新生,换电池、背盖,升级android11
  7. shell基础入门1.1shell特性
  8. python中什么是句柄_python中的句柄操作的方法示例
  9. CC00072.pbpositions——|HadoopPB级数仓.V01|——|PB数仓.v01|Griffin数据质量监控工具|概述|
  10. 2013-2019年百度搜索算法规则解读与应对
  11. Python 电脑上自动阅读东方头条
  12. PYTHON将成绩从百分制变换到等级制
  13. 定时任务与网页去重、代理的使用
  14. python实现Excel中的数据透视表功能
  15. 二手书交易平台相关调研
  16. Java程序员花十个月做私活,收入50w+,网友:老哥建个群搭个伙呗
  17. conda环境名称消失问题
  18. 计算机知识竞赛心得体会,知识竞赛活动心得范文【两篇】
  19. 机器学习实战 基于_[编程]-机器学习实战-概览
  20. arduino灯带随音乐_party神器~ProcessingArduino音乐LED

热门文章

  1. npm start 作用
  2. javascript onclick中post提交
  3. [转]Getting Start With Node.JS Tools For Visual Studio
  4. 模式6--ReadWriteLock
  5. 从.NET1.1升级到.NET2.0时出现的PInvokeStackImbalance错误
  6. pat 食物链(状态压缩求哈密顿回路)
  7. php如何对数组进行分组,如何在PHP中对数组进行分组排序
  8. python刷题笔记怎么改_python面试题刷题笔记1 - 10
  9. linux按文件名排序ls,linux – 如何使用shell脚本按名称对文件进行排序
  10. echarts词云第一次出现不了数据要刷新才能出现_红米K30 4G版评测:1599元的120Hz屏幕刷新率...