嵌入式学习笔记 D21:双向链表的基本操作
- 双向链表的定义与创建
- 双向链表的插入
- 双向链表的查找
- 双向链表的修改
- 双向链表的删除
- 双向链表的逆序
- MakeFile工具使用
一、双向链表的定义与创建
1.双向链表的定义:
双向链表是在单链表的每个结点中,再设置一个指向其前一个结点的指针域。
struct DOUNode
{struct DATATYPE data;struct DOUNode *prev;struct DOUNode *next;};
2.双向链表的创建
struct DOULinkList* CreateDouLinkList()
{struct DOULinkList *dl = (struct DOULinkList*)malloc(sizeof(struct DOULinkList));if(NULL == dl){fprintf(stderr,"CreateDouLinkList malloc");return NULL;}dl->head = NULL;dl->clen = 0;return dl;}
二、双向链表的插入
1.头插法:
int InsertHeadDouLinkList(struct DOULinkList* dl, struct DATATYPE* data)
{struct DOUNode *newnode = malloc (sizeof(struct DOUNode));if (NULL == newnode) {fprintf(stderr, "InsertHeadDouLinkList malloc");return 1;}memcpy(&newnode->data,data,sizeof(struct DATATYPE));newnode->next = NULL;newnode->prev = NULL;newnode->next = dl->head;if(dl->head){dl->head->prev = newnode;}dl->head = newnode;dl->clen++;return 0;}
2.尾插法:
int InsertTailDouLinkList(struct DOULinkList* dl, struct DATATYPE* data)
{if(IsEmptyDouLinkList(dl)){return InsertHeadDouLinkList(dl,data);}else{struct DOUNode *tmp = dl->head; while(tmp->next){tmp = tmp->next;}struct DOUNode *newnode =(struct DOUNode *) malloc (sizeof(struct DOUNode));if (NULL == newnode) {fprintf(stderr, "InsertTailDouLinkList malloc");return 1;}// chu shi hua jie dianmemcpy(&newnode->data,data,sizeof(struct DATATYPE));newnode->next = NULL;newnode->prev = NULL;// lian jie lian biaonewnode->prev = tmp;tmp->next = newnode;dl->clen++;}return 0;
}
3.按指定位置插入:
int InsertPosDouLinkList(struct DOULinkList* dl, struct DATATYPE* data,int pos)
{int len = GetSizeDouLinkList(dl);if(pos < 0 || pos > len){return 1;}if( 0 == pos){return InsertHeadDouLinkList(dl, data);}else if(pos == len){return InsertTailDouLinkList(dl,data);}else {struct DOUNode *newnode =(struct DOUNode *) malloc (sizeof(struct DOUNode));if (NULL == newnode) {fprintf(stderr, "InsertPosDouLinkList malloc");return 1;}// chu shi hua jie dianmemcpy(&newnode->data,data,sizeof(struct DATATYPE));newnode->next = NULL;newnode->prev = NULL;struct DOUNode *tmp = dl->head; int i ;for( i = 0; i < pos ; ++i){tmp = tmp->next;}newnode->next = tmp;newnode->prev = tmp->prev;tmp->prev = newnode;newnode->prev->next = newnode;dl->clen++;}return 0;
}
4.链表的遍历:
int ShowDouLinkList(struct DOULinkList* dl, DIR dir)
{struct DOUNode *tmp = dl->head;if(FORWADR == dir){while(tmp){printf("%s %c %d %d\n", tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);tmp = tmp->next;}}else if( BACKWADR == dir){while(tmp->next){tmp = tmp->next;}while(tmp){printf("%s %c %d %d\n", tmp->data.name,tmp->data.sex,tmp->data.age,tmp->data.score);tmp = tmp->prev;}}return 0;
}
5.判断链表是否为空
int IsEmptyDouLinkList(struct DOULinkList *dl)
{return 0 == dl->clen;
}
6.获取链表的长度
int GetSizeDouLinkList(struct DOULinkList *dl)
{return dl->clen;
}
三、双向链表的查找
struct DOUNode *FindDouLinkList(struct DOULinkList *dl,char *name)
{if(IsEmptyDouLinkList(dl)){return NULL;}struct DOUNode *tmp = dl->head;while(tmp){if(0 == strcmp(tmp->data.name,name)){return tmp;}tmp = tmp->next;}return NULL;
}
四、双向链表的修改
int ModifyDouLinkList(struct DOULinkList *dl,char *name, struct DATATYPE* data)
{struct DOUNode *tmp = FindDouLinkList(dl,name);if(NULL == tmp){return 1;}memcpy(&tmp->data, data, sizeof(struct DATATYPE));return 0;}
五、双向链表的删除
1.链表的清空:
int DestoryDouLinkList(struct DOULinkList **dl)
{struct DOUNode *tmp = (*dl)->head;while(tmp){if(NULL == tmp){break;}(*dl)->head = (*dl)->head->next;free(tmp);tmp = (*dl)->head;}free(*dl);*dl = NULL;return 0;
}
2.链表的删除:
int DeleteDouLinkList(struct DOULinkList *dl, char *name)
{if(IsEmptyDouLinkList(dl)){return 1;}struct DOUNode *tmp = FindDouLinkList(dl,name);if(dl->head == tmp){dl->head = dl->head->next;dl->head->prev = NULL;free(tmp);dl->clen--;}else if(tmp->next == NULL){tmp->prev->next = NULL;tmp->prev = NULL;free(tmp);dl->clen--;}else{tmp->prev->next = tmp->next;tmp->next->prev = tmp->prev;tmp->prev = NULL;tmp->next = NULL;dl->clen--;}return 0;
}
六、双向链表的逆序
int InverseDouLinkList(struct DOULinkList *dl)
{if(IsEmptyDouLinkList(dl)){return 1;}int len = GetSizeDouLinkList(dl);if( 1 == len){return 0;}struct DOUNode *prev = NULL;struct DOUNode *tmp = dl->head;struct DOUNode *next = dl->head->next;while(1){tmp->next = prev;tmp->prev = next;prev = tmp;tmp = next;if(NULL == tmp){break;}next = next->next;}dl->head = prev;return 0;
}
七、MakeFile工具使用
三个.c以上可以使用。
1.方法一:
a.out(目标):main.c ./doulink (依赖)gcc main.c doulink.c//前面空一个Tab键
clean:rm a.out
在终端敲make,进行编译,若要指定makefile ,加-f再加指定makefile。
2.方法二:
#代表源文件
SRC += main.c(变量名任取)//指定变量
SRC += doulink.c
DST = app(可执行文件)CC = gcc//编译器
FLAG = -g
LIB = -lm$(DST):$(SRC)$(CC) $(SRC) $(FLAG) $(LIB)-o(指定名字) $(DST)
clean:rm $(DST)
相关文章:
嵌入式学习笔记 D21:双向链表的基本操作
双向链表的定义与创建双向链表的插入双向链表的查找双向链表的修改双向链表的删除双向链表的逆序MakeFile工具使用 一、双向链表的定义与创建 1.双向链表的定义: 双向链表是在单链表的每个结点中,再设置一个指向其前一个结点的指针域。 struct DOUNode…...

让AI帮我写一个word转pdf的工具
需求分析 前几天,一个美女找我: 阿瑞啊,能不能帮我写个工具,我想把word文件转为pdf格式的 我说:“你直接网上搜啊,网上工具多了去了” 美女说: 网上的要么是需要登录注册会员的,要…...

OrangePi Zero 3学习笔记(Android篇)10 - SPI和从设备
目录 1. 配置内核 2. 修改设备数 3. 修改权限 4. 验证 Zero 3的板子有2个SPI Master接口,其中SPI0接的是板载16MB大小的SPI Nor Flash,SPI1则是导出到26pin的接口上。 spi和i2c有点不同,spi是直接生成spi虚拟设备,所以在dev里…...

基于策略的强化学习方法之近端策略优化(PPO)深度解析
PPO(Proximal Policy Optimization)是一种基于策略梯度的强化学习算法,旨在通过限制策略更新幅度来提升训练稳定性。传统策略梯度方法(如REINFORCE)直接优化策略参数,但易因更新步长过大导致性能震荡或崩溃…...
跨境电商定价革命:亚马逊“逆向提价“策略背后的价值重构逻辑
导言:打破价格魔咒的销量奇迹 2024年Q3亚马逊平台上演商业悖论:在TOP5000卖家中,12%实施5%-15%温和提价的商户,41%实现单量30.4%的季度增长。这一现象颠覆"低价即流量"的电商铁律,揭开新消费时代"价值定…...

文章复现|(1)整合scRNA-seq 和空间转录组学揭示了子宫内膜癌中 MDK-NCL 依赖性免疫抑制环境
https://www.frontiersin.org/journals/immunology/articles/10.3389/fimmu.2023.1145300/full 目标:肿瘤微环境(TME)在子宫内膜癌(EC)的进展中起着重要作用。我们旨在评估EC的TME中的细胞群体。 方法:我们从GEO下载了EC的单细胞RNA测序(scRNA-seq)和空…...

HTML-3.4 表单form
本系列可作为前端学习系列的笔记,代码的运行环境是在HBuilder中,小编会将代码复制下来,大家复制下来就可以练习了,方便大家学习。 系列文章目录 HTML-1.1 文本字体样式-字体设置、分割线、段落标签、段内回车以及特殊符号 HTML…...
阿克曼-幻宇机器人系列教程3- 机器人交互实践(Message)
上一篇文章介绍了如何通过topic操作命令实现与机器人的交互,本篇我们介绍如何通过Message(即topic的下一级)实现与机器人的交互。 和topic一样,首先在一个终端通过ssh命令登录机器人、启动机器人,然后打开另外一个终端…...

【MySQL】服务器配置与管理(相关日志)
🔥个人主页: 中草药 🔥专栏:【MySQL】探秘:数据库世界的瑞士军刀 一、系统变量和选项 当通过mysqld启动数据库服务器时,可以通过选项文件或命令行中提供选项。一般,为了确保服务器在每次运行时…...

【问题】Watt加速github访问速度:好用[特殊字符]
前言 GitHub 是全球知名的代码托管平台,主要用于软件开发,提供 Git 仓库托管、协作工具等功能,经常要用到,但是国内用户常因网络问题难以稳定访问 。 Watt Toolkit(原名 Steam)是由江苏蒸汽凡星科技有限公…...

vue3:十三、分类管理-表格--行内按钮---行删除、批量删除实现功能实现
一、实现效果 增加行内按钮的样式效果,并且可以根绝父组件决定是否显示 增加行内删除功能、批量删除功能 二、增加行内按钮样式 1、增加视图层按钮 由于多个表格都含有按钮功能,所以这里直接在子组件中加入插槽按钮 首先增加表格行<el-table-column></el-table-…...
Web3.0:互联网的去中心化未来
随着互联网技术的不断发展,我们正站在一个新时代的门槛上——Web3.0时代。Web3.0不仅仅是一个技术升级,它更是一种全新的互联网理念,旨在通过去中心化技术重塑网络世界。本文将深入探讨Web3.0的核心概念、技术基础、应用场景以及它对未来的深…...

浏览器设置代理ip后不能上网?浏览器如何改ip地址教程
使用代理IP已成为许多用户保护隐私、绕过地域限制或进行网络测试的常见做法。当浏览器设置代理IP后无法上网时,通常是由于代理配置问题或代理服务器本身不可用。以下是排查和解决问题的详细步骤,以及更改浏览器IP的方法: 一、代理设置后无法上…...
Java应用OOM排查:面试通关“三部曲”心法
开篇点题:OOM——Java应用的“内存爆仓”警报 OOM (OutOfMemoryError) 是啥病?想象一下,你的Java应用程序是一个大仓库,内存就是仓库的存储空间。如果货物(程序运行时创建的对象)越来越多,超出了…...

R语言的专业网站top5推荐
李升伟 以下是学习R语言的五个顶级专业网站推荐,涵盖教程、社区、资源库和最新动态: 1.R项目官网 (r-project.org) R语言的官方网站,提供软件下载、文档、手册和常见问题解答。特别适合初学者和高级用户,是获取R语言核心资源的…...
设计模式系列(03):设计原则(二):DIP、ISP、LoD
本文为设计模式系列第3篇,聚焦依赖倒置、接口隔离、迪米特法则三大设计原则,系统梳理定义、实际业务场景、优缺点、最佳实践与常见误区,适合系统学习与团队协作。 目录 1. 引言2. 依赖倒置原则(DIP)3. 接口隔离原则(ISP)4. 迪米特法则(LoD)5. 常见误区与反例6. 最佳实…...
Java Socket编程完全指南:从基础到实战应用
Socket编程是构建网络应用的基石,Java通过java.net包提供了强大的Socket API。本文将深入解析Java Socket类的核心用法,涵盖TCP/UDP协议实现、多线程通信及性能优化技巧,助您快速掌握网络编程精髓。 一、Socket编程核心概念 1.1 网络通信模型…...

[训练和优化] 3. 模型优化
👋 你好!这里有实用干货与深度分享✨✨ 若有帮助,欢迎: 👍 点赞 | ⭐ 收藏 | 💬 评论 | ➕ 关注 ,解锁更多精彩! 📁 收藏专栏即可第一时间获取最新推送🔔…...
基于FPGA的车速检测系统仿真设计与实现
标题:基于FPGA的车速检测系统仿真设计与实现 内容:1.摘要 本文旨在设计并实现基于FPGA的车速检测系统仿真。随着汽车行业的快速发展,精确的车速检测对于车辆的安全性和性能评估至关重要。本研究采用FPGA作为核心处理单元,结合传感器数据采集与处理技术进…...

无人设备遥控器之无线通讯技术篇
无人设备遥控器的无线通讯技术是确保遥控操作准确、稳定、高效进行的关键。以下是对无人设备遥控器无线通讯技术的详细解析: 一、主要无线通讯技术类型 Wi-Fi通讯技术 原理:基于IEEE 802.11标准,通过无线接入点(AP)…...
Redis(2):Redis + Lua为什么可以实现原子性
Redis 作为一款高性能的键值对存储数据库,与 Lua 脚本相结合,为实现原子性操作提供了强大的解决方案,本文将深入探讨 Redis Lua 实现原子性的相关知识 原子性概念的厘清 在探讨 Redis Lua 的原子性之前,我们需要明确原子性的概念…...

PyTorch LSTM练习案例:股票成交量趋势预测
文章目录 案例介绍源码地址代码实现导入相关库数据获取和处理搭建LSTM模型训练模型测试模型绘制折线图主函数 绘制结果 案例介绍 本例使用长短期记忆网络模型对上海证券交易所工商银行的股票成交量做一个趋势预测,这样可以更好地掌握股票买卖点,从而提高…...

CK3588下安装linuxdeployqt qt6 arm64
参考资料: Linux —— linuxdeployqt源码编译与打包(含出错解决) linux cp指令报错:cp: -r not specified; cp: omitting directory ‘xxx‘(需要加-r递归拷贝) CMake Error at /usr/lib/x86_64…...

木马查杀引擎—关键流程图
记录下近日研究的木马查杀引擎,将关键的实现流程图画下来 PHP AST通道实现 木马查杀调用逻辑 模型训练流程...

二程运输的干散货船路径优化
在二程运输中,干散货船需要将货物从一个港口运输到多个不同的目的地港口。路径优化的目标是在满足货物运输需求、船舶航行限制等条件下,确定船舶的最佳航行路线,以最小化运输成本、运输时间或其他相关的优化目标。 影响因素 港口布局与距离:各个港口之间的地理位置和距离…...

华为数字政府与数字城市售前高级专家认证介绍
华为数字政府与数字城市售前高级专家认证面向华为合作伙伴售前高级解决方案专家、华为数字政府与数字城市行业解决方案经理(VSE)。 通过认证验证的能力 您将了解数字政府、数字城市行业基础知识,了解该领域内的重点场景;将对华…...
在VSCode中接入DeepSeek的指南
本文将介绍三种主流接入方式,涵盖本地模型调用和云端API接入方案。 一、环境准备 1.1 基础要求 VSCode 1.80+Node.js 16.x+Python 3.8+(本地部署场景)已部署的DeepSeek服务(本地或云端)1.2 安装必备插件 # 打开VSCode插件面板(Ctrl+Shift+X) 搜索并安装: - DeepSeek Of…...

【docker】--容器管理
文章目录 容器重启--restart 参数选项及作用**对比 always 和 unless-stopped****如何查看容器的重启策略?** 容器重启 –restart 参数选项及作用 重启策略 no:不重启(默认)。on-failure:失败时重启(可限…...

基于OpenCV的人脸微笑检测实现
文章目录 引言一、技术原理二、代码实现2.1 关键代码解析2.1.1 模型加载2.1.2 图像翻转2.1.3 人脸检测 微笑检测 2.2 显示效果 三、参数调优建议四、总结 引言 在计算机视觉领域,人脸检测和表情识别一直是热门的研究方向。今天我将分享一个使用Python和OpenCV实现…...
使用PEFT库将原始模型与LoRA权重合并
使用PEFT库将原始模型与LoRA权重合并 步骤如下: 基础模型加载:需保持与LoRA训练时相同的模型配置merge_and_unload():该方法会执行权重合并并移除LoRA层保存格式:合并后的模型保存为标准HuggingFace格式,可直接用于推…...