发布时间:2026/8/6 9:04:58
RTT学习-双向链表 一、为什么 RTOS 内核需要双向链表在 RT-Thread 中双向链表是组织内核对象的重要基础。链表中的每个节点都保存两个指针next指向直接后继节点prev指向直接前驱节点。与单向链表相比双向链表可以从任意节点向前或向后遍历。更重要的是在已经获得目标节点地址的前提下插入和删除节点都只需要修改固定数量的指针时间复杂度为O(1)。需要注意双向链表并不会让“按值查找”变成O(1)。如果没有目标节点的地址仍然需要遍历链表时间复杂度为O(n)。它的优势主要体现在双向遍历以及已知节点位置时的快速插入、删除。二、RT-Thread 双向链表的结构课件版本中链表节点定义在rttypes.h/** * Double List structure */ struct rt_list_node { struct rt_list_node *next; /** point to next node. */ struct rt_list_node *prev; /** point to prev node. */ }; ​ typedef struct rt_list_node rt_list_t;rt_list_t既可以表示普通节点也可以表示链表头。RT-Thread 使用的是循环双向链表初始化后的头结点满足head.next head head.prev head可以把空链表理解为头结点的两个指针都绕回自己这里的head是哨兵头结点不存放实际业务数据。它让空链表、首节点和尾节点都能采用统一的指针操作减少边界条件判断。三、链表初始化RT-Thread 提供了宏初始化和内联函数初始化两种方式课件版本中均定义在rtservice.h。1. 使用宏初始化#define RT_LIST_OBJECT_INIT(object) { (object), (object) } ​ rt_list_t list RT_LIST_OBJECT_INIT(list);这种方式适合在定义链表对象时直接完成初始化。2. 使用函数初始化rt_inline void rt_list_init(rt_list_t *l) { l-next l-prev l; } ​ rt_list_t list; rt_list_init(list);这种方式适合链表对象已经定义之后再进行初始化的场景。无论采用哪种方式本质都是让next和prev指向节点自身。初始化不是可选步骤未初始化的指针参与插入或删除会导致非法内存访问。四、在指定节点之后插入1. 函数实现rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n) { l-next-prev n; /* 1 */ n-next l-next; /* 2 */ l-next n; /* 3 */ n-prev l; /* 4 */ }假设原链表局部关系为A - C现在要把新节点B插入A之后最终关系应变为A - B - C四条语句分别完成C.prev B让原后继节点C的前驱指向BB.next C让B的后继指向CA.next B让A的后继指向BB.prev A让B的前驱指向A。关键点是先保存并使用原有连接关系再改写l-next。如果过早覆盖原指针就可能丢失节点C的地址。2. 基本用法rt_list_t list RT_LIST_OBJECT_INIT(list); rt_list_t *new_node rt_malloc(sizeof(rt_list_t)); ​ if (new_node ! RT_NULL) { rt_list_insert_after(list, new_node); }当参数l是哨兵头结点list时rt_list_insert_after(list, new_node)会把新节点放到链表首部。五、在指定节点之前插入1. 函数实现rt_inline void rt_list_insert_before(rt_list_t *l, rt_list_t *n) { l-prev-next n; /* 1 */ n-prev l-prev; /* 2 */ l-prev n; /* 3 */ n-next l; /* 4 */ }假设原链表局部关系为C - A将新节点B插入A之前最终关系为C - B - A四条语句分别完成C.next B让原前驱节点C的后继指向BB.prev C让B的前驱指向CA.prev B让A的前驱指向BB.next A让B的后继指向A。2. 基本用法rt_list_t list RT_LIST_OBJECT_INIT(list); rt_list_t *new_node rt_malloc(sizeof(rt_list_t)); ​ if (new_node ! RT_NULL) { rt_list_insert_before(list, new_node); }由于链表是循环结构头结点的前驱就是尾节点。因此rt_list_insert_after(list, new_node)插入到链表首部rt_list_insert_before(list, new_node)插入到链表尾部。六、删除指定节点1. 函数实现rt_inline void rt_list_remove(rt_list_t *n) { n-next-prev n-prev; /* 1 */ n-prev-next n-next; /* 2 */ n-next n-prev n; /* 3 */ }假设待删除节点为BA - B - C删除后变为A - C B - B执行过程如下C.prev A让后继节点跳过B直接指向AA.next C让前驱节点跳过B直接指向CB.next B.prev B让被删除节点恢复为自环状态。第三步很有意义删除后的节点不再保留指向原链表的悬空关系而且在结构上重新成为一个独立的空链表节点。2. 删除与释放内存不是一回事rt_list_remove()只负责把节点从链表中摘除并不会释放节点占用的内存。如果节点是动态申请的可以在摘链后释放rt_list_t *del_node /* 指向链表中的某个动态节点 */; ​ rt_list_remove(del_node); rt_free(del_node); del_node RT_NULL;这里要特别区分“对象”和“指针”/* del_node 是对象传入它的地址 */ rt_list_t del_node; rt_list_remove(del_node); ​ /* del_node 是指针直接传入指针值 */ rt_list_t *del_node /* ... */; rt_list_remove(del_node);只有通过rt_malloc()等接口动态分配的内存才应交给rt_free()。如果链表节点是静态对象、栈对象或嵌入在其他结构体中就不能直接释放该节点地址。七、四个核心操作对比操作核心效果时间复杂度rt_list_init(l)让l-next、l-prev都指向lO(1)rt_list_insert_after(l, n)将n插入l后面O(1)rt_list_insert_before(l, n)将n插入l前面O(1)rt_list_remove(n)将已知节点n从链表摘除O(1)链表的遍历和按条件查找仍然是O(n)。八、把指针操作记成三个模板1. 初始化自己指向自己next self prev self2. 插入先接新节点两侧再替换原连接原来A - C 插入A - B - C插入操作始终需要建立四条连接A.next B B.prev A B.next C C.prev B3. 删除前后节点互连删除节点自环原来A - B - C 删除A - CB 自环对应的核心关系是A.next C C.prev A B.next B.prev B

相关新闻

2026/8/6 9:04:58

用AI自动承接私信,解决短视频运营人手不足难题

短视频运营新解法:利用AI自动化承接私信,缓解人力瓶颈对于许多初创团队、个体经营者以及中小企业主而言,同时维护多个社交平台账号是一项极具挑战的任务。手动回复海量私信、实时查看评论以及保持账号的日常活跃度,往往占据了运营…

2026/8/6 9:04:58

通信系统ADC性能评估实战:从SNR与SFDR测试到链路预算映射

1. 项目概述:为什么通信系统工程师必须关注ADC的SNR与SFDR?在通信系统的硬件设计里,模数转换器(ADC)的性能评估从来都不是一个可以“差不多就行”的环节。你可能已经熟练地在STM32或者ESP32上配置了ADC,完成…

2026/8/6 9:55:00

《一拳超人》深度解析:反套路英雄叙事与存在主义内核

1. 为什么《一拳超人》值得一看?一个资深动漫迷的深度安利如果你最近在找一部能让你彻底放松、笑出声,同时又忍不住思考的动漫,那么《一拳超人》绝对应该在你的待看清单里。这部作品在动漫圈里已经火了很久,但每次向人推荐&#x…

2026/8/6 9:55:00

笔下科技科技车路协同沙盘中自动驾驶小车

笔下科技科技车路协同沙盘中自动驾驶小车的核心技术实现路径笔下科技科技的智能网联实训沙盘充分诠释了 “微缩城市路网,实练智驾内核” 的建设理念,整套系统以车载智能小车为执行载体,完整搭建感知决策规划控制技术闭环,在缩小版…

2026/8/6 9:55:00

论文格式总是调不对,有哪些便捷的一键生成论文工具推荐?

每到毕业季,不少同学卡在开题报告这第一道坎上:选题定不下来、研究背景和意义分不清、文献综述无从下手、研究方法和技术路线逻辑混乱,对着空白文档熬上几周也写不出完整框架。尤其是零基础、在职读研、跨专业的学生,对高校开题规…

2026/8/6 9:50:00

联邦学习实战指南:原理、挑战与Python实现

1. 从“数据孤岛”到“联邦”的必然之路如果你在数据科学、机器学习或者隐私计算领域摸爬滚打过一段时间,大概率会反复听到一个词——“数据孤岛”。这玩意儿就像公司里那些上了锁的、互不相通的保险柜,每个部门都守着自己的宝贝数据,生怕别人…

2026/8/5 3:13:11

如何用免费工具突破游戏窗口限制:SRWE完整使用指南

如何用免费工具突破游戏窗口限制:SRWE完整使用指南 【免费下载链接】SRWE Simple Runtime Window Editor 项目地址: https://gitcode.com/gh_mirrors/sr/SRWE 你是否遇到过这样的困扰?想为心爱的游戏截图,却发现游戏不支持自定义分辨率…

2026/8/6 0:04:22

电力系统调度中的源荷不确定性建模与优化实践

1. 电力系统调度中的源荷不确定性挑战现代电力系统正面临前所未有的复杂性,其中源荷不确定性(Source-Load Uncertainty)已成为调度决策中最棘手的难题之一。我在参与某省级电网调度系统升级时,曾遇到风电预测误差导致日内调度计划…

2026/8/6 0:04:22

VGG-T3技术解析:3D重建速度的革命性突破

1. 项目概述:VGG-T3如何重新定义3D重建速度在计算机视觉领域,3D场景重建一直是个计算密集型任务。传统方法重建1000帧图像规模的场景往往需要数小时甚至更长时间,而英伟达最新发布的VGG-T3技术将这个时间压缩到了惊人的54秒。这个突破性进展来…

2026/8/6 0:04:22

深度解析旅游网站建设的意义及其对行业发展的深远影响与核心价值体现

在这个数字化浪潮席卷全球的今天,我们似乎已经忘记了,曾经有一段时间,人们想要去一个陌生的地方,只能靠在书桌前翻阅厚厚的旅游杂志,或者向刚从那里回来的朋友询问那些模糊不清的印象。那时候,“远方”是一个需要精打细算才能抵达的奢侈概念。而现在,只需要一部手机,轻…

2026/8/5 19:21:13

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/5 19:21:13

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/5 19:21:13

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…