一、内核链表基础

1. 什么是 Linux 内核链表?

Linux 内核链表是一种高效的 双向循环链表,广泛应用于内核模块开发中,用于管理数据结构。每个节点通过指针连接前一个和后一个元素,实现插入和删除的高性能。

2. 链表的定义与初始化

在 Linux 内核中,链表的实现依赖于 struct list_head 结构体,定义在头文件 <linux/list.h> 中:

struct list_head {
struct list_head *next, *prev;
};

为了在自定义结构体中集成链表,只需在结构体中包含 list_head 成员即可:

struct my_data {
int value;
struct list_head list;
}

链表初始化使用如下宏:

LIST_HEAD(my_list); // 静态初始化
// 或者
INIT_LIST_HEAD(&my_list); // 动态初始化

这两种方式都将 list.nextlist.prev 指向自身,构成一个空的循环链表。

注意:内核链表已经将增删查改封装好了,开发者只需要聚焦于数据部分。


3. 内核链表设计思想

  • 普通链表将数据和节点结构紧耦合。

  • 内核链表则通过将链表节点作为结构体中的一个字段,从而实现结构体与链表解耦。

常用宏如下:

  • offsetof():用于计算某个成员在结构体中的偏移量。

  • container_of():用于通过结构体成员地址获取整个结构体指针。

#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))


4. 常用链表操作宏与函数

功能宏 / 函数名称说明
添加节点list_add / list_add_tail添加到链表头/尾
删除节点list_del将节点从链表中移除
遍历链表list_for_each遍历每一个节点(通用)
遍历链表list_for_each_entry遍历包含结构体的链表

5. 使用链表需注意的要点

  • 内存管理:新增节点前需手动分配内存;删除节点后应释放。

  • 线程安全:多线程环境下需加锁。

  • 性能考量:链表适合插入/删除频繁场景,但查找效率低。


二、栈(Stack)

1. 基本定义

栈是一种 只允许在一端(栈顶)进行插入和删除操作 的线性结构,遵循 后进先出(LIFO) 原则。

在 C 语言中,我们通常用动态内存(堆区)来实现线性栈结构。

2. 结构特点

  • 栈顶(top):允许插入/删除的一端。

  • 栈底(bottom):固定不动的一端。

  • 空栈:栈中无任何数据元素。

3. 栈的类型

  • 满增栈:栈满时从低地址向高地址增长。

  • 空减栈:从高地址向低地址扩展。

  • 实际实现时通常选择一种逻辑来处理栈顶移动。

📌 示例说明

栈空间从底部开始增长,压栈操作使 top++,出栈使 top--。如果 top 达到容量限制,表示栈已满。

4. 栈的应用场景

  • 递归求解 / 回溯问题

  • 表达式求值(符号优先级)

  • 函数调用管理(程序栈帧)


5. 栈的基本操作代码

#include <stdio.h>
#include "stack.h"
#include <stdlib.h>Stack *creatStack()
{Stack *pstack = malloc(sizeof(Stack));if(pstack == NULL){printf("malloc error\n");return NULL;}pstack->ptop = NULL;pstack->clen = 0;return pstack;
}int IsEmptyStack(Stack *pstack)
{return NULL == pstack->ptop;
}
int pushStack(Stack *pstack, DataType data)
{StNode *pnode = malloc(sizeof(StNode));if(NULL == pnode){printf("malloc error\n");return -1;}pnode->data = data;pnode->pnext = NULL;pnode->pnext = pstack->ptop;pstack->ptop = pnode;pstack->clen++;return 1;
}/*** @brief 出栈,且出栈之前保存栈顶的元素,通过主函数定义的dadatype类型返回改后的数值* * @param pstack 栈头指针* @param data 返回的栈顶元素的值* @return int 成功出栈返回1,失败为0*/
int popStack(Stack *pstack, DataType *data)
{if(IsEmptyStack(pstack)){return -1;}StNode *temp = pstack->ptop;*data = temp->data;pstack->ptop = temp->pnext;free(temp);pstack->clen--;return 1;
}/*** @brief Get the Stack Top object* * @param pstack * @param data * @return int */
int getStackTop(Stack *pstack, DataType *data)
{if(IsEmptyStack(pstack)){return -1;}*data = pstack->ptop->data;return 1;
}void printStack(Stack *pstack)
{if(IsEmptyStack(pstack)){return ;}StNode *temp = pstack->ptop;while(temp){printf("%d ", temp->data);temp = temp->pnext;}puts("");return ;
}void destroyStack(Stack **pstack)
{StNode *temp = (*pstack)->ptop;while(temp){(*pstack)->ptop = temp->pnext;free(temp);temp = (*pstack)->ptop;}free(*pstack);*pstack = NULL;
}

三、队列(Queue)

1. 基本定义

队列是一种**先进先出(FIFO)**的数据结构,特点是:

  • 队尾(tail) 进入数据

  • 队头(head) 移除数据

2. 队列的应用场景

  • 缓冲区管理

  • 数据包调度

  • 多任务之间的通信机制


3. 循环队列(环形队列)

为避免频繁移动数据,可将队列逻辑设计为循环结构。即:利用数组,头尾指针移动时利用求余操作形成环形效果。

next = (tail + 1) % MAX_LEN;

判断条件:
队列状态条件
队空head == tail
队满(tail + 1) % MAX == head

4. 队列的类型

  • 顺序队列(数组实现)

  • 链式队列(链表实现,扩展性强)


5. 链表型队列的代码

#include <stdio.h>
#include "linkqueue.h"
#include <stdlib.h>LQueue *creatQLink()
{LQueue *plink = malloc(sizeof(LQueue));if(NULL == plink){fprintf(stderr, "malloc error\n");return NULL;}plink->phead = NULL;plink->ptail = NULL;plink->clen = 0;return plink;
}int isEmptyLQueue(LQueue *plink)
{return NULL == plink->phead;
}int pushLQueue(LQueue *plink, DataType data)
{LQNode *pnode = malloc(sizeof(LQNode));if(pnode == NULL){fprintf(stderr, "malloc error\n");return -1;}pnode->data = data;pnode->pnext = NULL;if(isEmptyLQueue(plink)){plink->phead = pnode;plink->ptail = pnode;plink->clen++;}else{plink->ptail->pnext = pnode;plink->ptail = pnode;plink->clen++;}return 0;
}int popLQueue(LQueue *plink)
{if(isEmptyLQueue(plink)){fprintf(stderr,"is empty lqueue\n");return -1;}LQNode *temp = plink->phead;plink->phead = temp->pnext;if(NULL == temp->pnext){plink->ptail = NULL;}free(temp);plink->clen--;return 0;
}LQNode* getLQueueHeadNode(LQueue *plink)
{if(isEmptyLQueue(plink)){fprintf(stderr, "empty Lqueue\n");return NULL;}return plink->phead;
}void printLQueue(LQueue *plink)
{if(isEmptyLQueue(plink)){fprintf(stderr, "empty lqueue\n");return ;}LQNode *temp = plink->phead;while(temp){printf("%d ", temp->data);temp = temp->pnext;}puts("");return ;
}void destroyLQueue(LQueue **plink)
{LQNode *temp = (*plink)->phead;while(temp){(*plink)->phead = temp->pnext;free(temp);temp = (*plink)->phead;}free(*plink);*plink = NULL;return ;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/92045.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/92045.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/92045.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

软考信息安全工程师11月备考

目前是在职备考&#xff0c;主业是移动端开发工程师。第一个月(8.4-9.6)&#xff0c;将分享完下面所有章节内容&#xff0c;平均不到两天更新一节1.网络信息安全概述2.网络攻击原理与常用方法3.密码学基本理论4.网络安全体系与网络安全模型5.物理与环境安全技术6.认证技术与原理…

使用DrissionPage实现xhs笔记自动翻页并爬取笔记视频、图片

使用DrissionPage实现xhs笔记自动翻页并爬取笔记视频、图片 声明: 本文章中所有内容仅供学习交流使用,不用于其他任何目的,不提供完整代码,抓包内容、敏感网址、数据接口等均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关! 本文章未经…

使用 input 上传文件, 选择文件后再次修改文件再上传失败( <input type=“file“ /> 自定义上传)

业务实际需求&#xff1a;点击【选择】按钮先选择文件&#xff0c;展示文件的详情&#xff1a;类型&#xff0c;大小&#xff0c;日期......点击【上传】按钮这个时候才去上传文件如图&#xff1a;BUG复现&#xff1a;点击上传文件后发现xlsx文件有些数据没填写&#xff0c;然后…

Win11 下解决 VScode/Trae 插件加载慢, 整个 VScode/Trae 很卡

最近在使用 Trae 写代码, 突然变得很卡, 尤其是插件系统, 比如我打开插件的面板, 以及比如我想预览一下写好的 .md 文件 (已安装了 Markdown Preview Enhanced 插件), 这些都要好几分钟才能打开. 最初以为是 Trae 坏掉了, 然后重启 Trae 不管用, 再重启电脑居然也不管用, 接着…

微型导轨:智能家居抽屉的智能化应用

当智能家居从“功能堆砌”转向“体验升级”&#xff0c;微型导轨凭借超薄结构、静音运行与精准定位能力&#xff0c;成为隐藏式设计、自动化交互的核心部件&#xff0c;让家具“动”得优雅且可靠。智能扫地机器人&#xff1a;微型导轨被应用于边刷的伸缩调节机构&#xff0c;能…

百套易语言教程、易语言视频教程【易语言编程入门教程】

百套易语言教程、易语言视频教程【易语言编程入门教程】 易语言辅助教程&#xff08;爱易编程论坛讲师 24课讲师&#xff1a;远航 9课爱易编程论坛讲师&#xff1a;爱易、小Call 8课&#xff09;.rar 时光论坛易语言全套教程【易语言零基础易语言抓包易语言填表】完整版.rar 易…

nlp-词汇分析

目录 一、语言中的词汇 1、词的形态学 2、词的词性 二、词语规范化 1、词语切分 2、词形还原 3、词干提取 三、中文分词 1、概述 2、基于最大匹配的中文分词 3、基于线性链条件随机场的中文分词 4、基于感知器的中文分词 词序列预测 模型参数学习 特征定义 5、…

Kafka ISR机制和Raft区别:副本数优化的秘密

Kafka的ISR机制和像Raft这样的传统基于Quorum&#xff08;法定人数&#xff09;的协议之间的区别确实很微妙&#xff0c;但也非常重要。让我们来分析一下为什么ISR可以减少所需的副本数量。在采用ISR模型和&#xff08;f1&#xff09;个副本数的配置下&#xff0c;一个Kafka分区…

新手向:GitCode疑难问题诊疗

Git疑难问题诊疗引言在软件开发过程中&#xff0c;版本控制系统&#xff08;VCS&#xff09;是不可或缺的工具&#xff0c;而Git以其分布式架构、强大的分支管理能力和高效的性能成为行业标准。然而&#xff0c;随着项目复杂度的提升&#xff0c;Git的使用也可能遇到各种疑难问…

电子电气架构 ---如何焕新升级为 48V 电气架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

JavaScript判断数字方法

在JavaScript中&#xff0c;判断一个值是否为数字有多种场景&#xff0c;以下是常见方法及适用情况&#xff1a;1. 严格判断数字类型&#xff08;排除NaN&#xff09;使用 typeof 结合 !isNaN()&#xff0c;确保值是 number 类型且非 NaN&#xff1a;javascriptfunction isNumb…

C++编程之旅-- -- --始探门庭的求知漫溯(二)

目录引用内联函数(C11)auto关键字基于范围的for循环指针空值---nullptr引用 引用&#xff1a;指将变量以另一个名称来展现的。它并非是一个新变量而是一个别名&#xff0c;它们同指一块内存空间。就如古时那些有字的人,亦或者是周树人&#xff0c;你说鲁迅是不是周树人呢&…

wordpress网站的“管理员邮箱地址”有什么用?

在WordPress网站的“设置”-“常规”中设置的“管理员邮箱地址”有多种用途&#xff0c;以下是详细介绍&#xff1a; 一、用户注册相关 密码找回功能 当网站用户忘记密码时&#xff0c;他们会通过点击登录页面上的“忘记密码”链接来重置密码。WordPress系统会向管理员邮箱地…

202506 电子学会青少年等级考试机器人六级实际操作真题

更多内容和历年真题请查看网站&#xff1a;【试卷中心 -----> 电子学会 ----> 机器人技术 ----> 六级】 网站链接 青少年软件编程历年真题模拟题实时更新 202506 青少年等级考试机器人实操真题六级 一、实际操作 1. 主题&#xff1a;姿态传感器交互步进电机左右…

Centos 安装 redis

1.下载redis&#xff0c;这个自己去网上找吧。2.上传文件&#xff0c;redis-7.4.1.tar.gz3.解压&#xff1a;执行 tar -xf redis-7.4.1.tar.gz在进行安装之前&#xff0c;检查一下有没有make、gcc、python3、没有的话全部 yum install。安装完之后&#xff0c;如果报一下错误&a…

算法训练营DAY55 第十一章:图论part05

并查集理论基础 背景 当我们需要判断两个元素是否在同一个集合里的时候&#xff0c;我们就要想到用并查集。 并查集主要有两个功能&#xff1a; 将两个元素添加到一个集合中。判断两个元素在不在同一个集合 原理讲解 从代码层面&#xff0c;我们如何将两个元素添加到同一个…

docker相关操作记录

1.docker清理服务器上面没有用到的镜像#删除本地镜像 docker rmi $(docker images -q) #强制删除本地镜像 docker rmi $(docker images -q) -f2.docker查看日志docker logs c36c56e4cfa3 (容器id)3.所有运行或没有运行的镜像 docker ps -a4、停止container&#xff0c;这样才…

LInux基础学习笔记七

/dev/zero和/dev/null 是什么/dev/zero&#xff1a;一个零设备文件&#xff0c;读取时会不断返回\0字节&#xff08;零值字节&#xff09;&#xff0c;常用于创建空文件或格式化/dev/null&#xff1a;一个空设备文件&#xff0c;写入它的内容会被丢弃&#xff0c;相当于“黑洞”…

软件架构:系统结构的顶层设计与战略约束

软件架构&#xff1a;系统结构的顶层设计与战略约束软件架构是软件系统的“骨架”与“宪法”&#xff0c;它定义了系统的根本性组织结构&#xff0c;包括构成系统的关键构件、它们之间的组织关系、交互机制、约束原则以及指导性决策。它决定了系统在性能、可扩展性、可靠性、可…

基于spring boot的个人博客系统

2 开发技术 3 2.1 VUE框架 3 2.2 Mysql数据库 3 2.3 Spring Boot框架 3 2.4 layui介绍 4 本程序在设计结构选择上首选B/S&#xff0c;也是为了满足程序今后升级便利&#xff0c;以及程序低维护成本的要求。本程序的网络拓扑设计也会在下图展示&#xff0c;通过图形的方式来描述…