C语言实验1—— C中的指针和结构体
问题
实现一个算法,检测单链表中是否有环,如果有环还要得到环的入口。
分析
判断是否有环:快慢指针法(也叫“龟兔赛跑”),慢指针每次移动一位,快指针每次移动两位,如果有环,他们一定会相遇。
求环的入口:到达相遇的位置时,将块指针移动到头指针的位置,每次移动一位,两者再次相遇的位置就是环的入口。
为什么呢?
(先“借”一张图

第一次相遇时,慢指针走 $x+k$,快指针走 $x+k+mr$($r$ 为环的长度, $m \geq 1$),
又因为快指针的速度是慢指针的两倍,所以 $2(x+k) = x+k+mr$.
即 $x = mr-k$($m \geq 1$),
慢指针已在 $k$ 处,块指针置0,还过 $x$ 步,它们就会相遇于环的入口。
#include <stdio.h>
#include<stdbool.h> typedef struct node {
int value;
struct node *next;
} node; bool ll_has_cycle(node *head) {
if (head == NULL) return false;
node* har = head;
node* tor = head; while ()
{
if (tor->next != NULL) tor = tor->next;
else return false;
if (har->next != NULL && har->next->next != NULL) har = har->next->next;
else return false; if (tor == har) return true;
}
} int find_cycle_entrance(node *head) {
if (head == NULL) return -;
node* har = head;
node* tor = head; while ()
{
if (tor->next != NULL) tor = tor->next;
else return -;
if (har->next != NULL && har->next->next != NULL) har = har->next->next;
else return -; if (tor == har)
{
har = head;
while(har != tor)
{
har = har->next;
tor = tor->next;
}
return har->value;
}
}
} void test_ll_has_cycle(void) {
int i;
node nodes[]; //enough to run our tests
for (i = ; i < sizeof(nodes) / sizeof(node); i++) {
nodes[i].next = ;
nodes[i].value = i;
}
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
printf("Checking first list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[]) ? "a" : "no");
printf("Entranc:%d\n", find_cycle_entrance(&nodes[])); nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
printf("Checking second list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[]) ? "a" : "no");
printf("Entranc:%d\n", find_cycle_entrance(&nodes[])); nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
printf("Checking third list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[]) ? "a" : "no");
printf("Entranc:%d\n", find_cycle_entrance(&nodes[])); nodes[].next = &nodes[];
printf("Checking fourth list for cycles. There should be a cycle, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[]) ? "a" : "no");
printf("Entranc:%d\n", find_cycle_entrance(&nodes[])); nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
nodes[].next = &nodes[];
printf("Checking fifth list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(&nodes[]) ? "a" : "no");
printf("Entranc:%d\n", find_cycle_entrance(&nodes[])); printf("Checking length-zero list for cycles. There should be none, ll_has_cycle says it has %s cycle\n", ll_has_cycle(NULL) ? "a" : "no");
printf("Entranc:%d\n", find_cycle_entrance(NULL));
} int main() {
test_ll_has_cycle();
return ;
}
参考链接:https://blog.csdn.net/qq_36781505/article/details/91401474
C语言实验1—— C中的指针和结构体的更多相关文章
- 【阅读笔记】《C程序员 从校园到职场》第七章 指针和结构体
原文地址:让你提前认识软件开发(13):指针及结构体的使用 CSDN博客 https://blog.csdn.net/zhouzhaoxiong1227/article/details/2387299 ...
- Android For JNI(五)——C语言多级指针,结构体,联合体,枚举,自定义类型
Android For JNI(五)--C语言多级指针,结构体,联合体,枚举,自定义类型 我们的C已经渐渐的步入正轨了,基础过去之后,就是我们的NDK和JNI实战了 一.多级指针 指针的概念我们在前面 ...
- C语言--- 高级指针2(结构体指针,数组作为函数参数)
一.结构体指针 1. 什么是结构体指针?指向结构体变量的指针 结构体: typedef struct stu{ char name[ ...
- c语言指针与结构体
#include <stdio.h> #include <stdlib.h> struct mydata { int num; ]; }; void main1() { /*i ...
- 嵌入式-C语言:通过结构体指针操作结构体内容
#include<stdio.h> #include<string.h> struct Student { char name[32]; int age; int height ...
- 嵌入式-C语言基础:通过结构体指针访问结构体数组
#include<stdio.h> #include<string.h> struct Student { char name[32]; int age; int height ...
- 深入理解C指针之六:指针和结构体
原文:深入理解C指针之六:指针和结构体 C的结构体可以用来表示数据结构的元素,比如链表的节点,指针是把这些元素连接到一起的纽带. 结构体增强了数组等集合的实用性,每个结构体可以包含多个字段.如果不用结 ...
- 36深入理解C指针之---结构体的内存处理
一.有关结构体的内存处理包括,结构体指针和结构体成员指针的内存分配.结构体成员的数据对齐.结构体的内存释放 1.定义:与自定义数据类型(结构体)有关的内存分配.大小和释放问题 2.特征: 1).用内存 ...
- C++指针和结构体基础知识
学习C++首先要回忆起C语言当中的指针和结构体知识,本文作者将通过一段代码来总结指针和结构体基础知识:指针是一个变量,其值为另一个变量的地址,即,内存位置的直接地址.就像其他变量或常量一样,您必须在使 ...
随机推荐
- react-native-typescript-项目环境搭建
1.yarn global add create-react-native-app //全局安装 2.create-react-native-app 项目名称 3.yarn add typescrip ...
- [转帖]Introduction to Linux monitoring and alerting
Introduction to Linux monitoring and alerting https://www.redhat.com/sysadmin/linux-monitoring-and-a ...
- Django content-type组件
介绍 Django包含一个contenttypes应用程序(app),可以跟踪Django项目中安装的所有模型(Model),提供用于处理模型的高级通用接口. Contenttypes应用的核心是Co ...
- bootstrap Modal或者 bootbox弹窗时,页面混动至顶部
bootstrap使用Modal时,页面自动滚动至了最顶部, 调用bootbox时,也是如此 查了半天资料,最后参考下述帖子,解决问题 https://stackoverflow.com/questi ...
- 如何将 Redis 用于微服务通信的事件存储
来源:Redislabs作者:Martin Forstner 翻译:Kevin (公众号:中间件小哥) 以我的经验,将某些应用拆分成更小的.松耦合的.可协同工作的独立逻辑业务服务会更易于构建和维护.这 ...
- [LOJ6433] [PKUSC2018] 最大前缀和
题目链接 LOJ:https://loj.ac/problem/6433 Solution 注意到最大前缀要满足什么性质,假设序列\(a[1..n]\)的最大前缀是\(s_x\),那么显然要满足所有\ ...
- 2.8_Database Interface ADO由来
OLE-DB,它无法广为流行,因为如下两点: 1.由于OLE-DB太底层化,使用上非常复杂,需要程序员拥有高潮的技巧. 2.OLEDB标准的API是C++API,只能供C++语言调用. 为了使得流行的 ...
- js 使用 "use strict"
"use strict"是JavaScript中一个非常好的特性,而且非常容易使用. 使用方法 // file.js "use strict" function ...
- 【洛谷 P4302】 [SCOI2003]字符串折叠(DP)
题目链接 简单区间dp 令\(f[i][j]\)表示\([i,j]\)的最短长度 先枚举区间,然后在区间中枚举长度\(k\),看这个区间能不能折叠成几个长度为\(k\)的,如果能就更新答案. #inc ...
- stack + positioned
stack 下套container, 发现最大的显示,小的都没显示, 把所有都套个POSITIONED, 都正常显示了.