嵌入式学习第三十一天!(双向链表)

        双向链表:在单向链表的每个结点中,再设置一个指向其前驱结点指针域(即牺牲部分空间,添加了一个前驱结点的指针域)

1. 双向链表的定义:

#ifndef _DOULINK_H_
#define _DOULINK_H_typedef struct stu
{int id;char name[32];int score;
}DATA_TYPE;typedef struct node
{DATA_TYPE data;struct node *pnext;struct node *ppre;
}DOU_NODE;typedef struct list
{DOU_NODE *phead;int curlen;
}DOU_LIST;typedef void (*PFUN_T)(DOU_NODE *);#endif

2. 双向链表句柄的创建:

DOU_LIST *Create_Dou_List(void)
{DOU_LIST *plist = malloc(sizeof(DOU_LIST));if(plist == NULL){perror("fail to malloc");return NULL;}plist->phead = NULL;plist->curlen = 0;return plist;
}

3. 双向链表结点的创建:

DOU_NODE *Creat_Node(DATA_TYPE data)
{DOU_NODE *pnode = malloc(sizeof(DOU_NODE));if(pnode == NULL){perror("fail to malloc");return NULL;}pnode->data = data;pnode->pnext = NULL;pnode->ppre = NULL;return pnode;
}

4. 双向链表的遍历:

void Dou_List_For_Each(DOU_LIST *plist, void (*pfun)(DOU_NODE *))
{DOU_NODE *ptmp = plist->phead;while(ptmp != NULL){pfun(ptmp);ptmp = ptmp->pnext;}#if 0   //反向遍历while(ptmp->pnext != NULL){ptmp = ptmp->pnext;}while(ptmp != NULL){printf("id = %d name = %s\t score = %02d\n", ptmp->data.id, ptmp->data.name, ptmp->data.score);ptmp = ptmp->ppre;}
#endifreturn;
}

5. 双向链表头插法:

int Is_Empty_Link(DOU_LIST *plist)
{return plist->phead == NULL;
}int Push_Head_Dou_Link(DOU_LIST *plist, DOU_NODE *pnode)
{if(plist == NULL || pnode == NULL){return -1;}if(Is_Empty_Link(plist)){plist->phead = pnode;}else{pnode->pnext = plist->phead;pnode->pnext->ppre = pnode;plist->phead = pnode;}plist->curlen++;return 0;
}

6. 双向链表尾插法:

int Push_Tail_Dou_Link(DOU_LIST *plist, DOU_NODE *pnode)
{if(plist == NULL || pnode == NULL){return -1;}if(Is_Empty_Link(plist)){plist->phead = pnode;}else{DOU_NODE *ptmp = plist->phead;while(ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->pnext = pnode;pnode->ppre = ptmp;}plist->curlen++;return 0;
}

7. 双向链表头删法:

int Pop_Head_Dou_Link(DOU_LIST *plist)
{if(Is_Empty_Link(plist)){return 0;}if(plist->phead->pnext == NULL){free(plist->phead);plist->phead = NULL;}else{DOU_NODE *ptmp = plist->phead;plist->phead = ptmp->pnext;ptmp->pnext->ppre = NULL;free(ptmp);}plist->curlen--;return 0;
}

8. 双向链表尾删法:

int Pop_Tail_Dou_Link(DOU_LIST *plist)
{if(Is_Empty_Link(plist)){return 0;}if(plist->phead->pnext == NULL){free(plist->phead);plist->phead = NULL;}else{DOU_NODE *ptmp = plist->phead;while(ptmp->pnext != NULL){ptmp = ptmp->pnext;}ptmp->ppre->pnext = NULL;free(ptmp);}plist->curlen--;return 0;
}

9. 双向链表找到数据的结点:

DOU_NODE *Find_Node(DOU_LIST *plist, DATA_TYPE data)
{DOU_NODE *ptmp = plist->phead;while(ptmp != NULL){if(!memcmp(&ptmp->data, &data, sizeof(data))){return ptmp;}ptmp = ptmp->pnext;}return NULL;
}

10. 双向链表替换数据:

int Replace_Node(DOU_LIST *plist, DATA_TYPE olddata, DATA_TYPE newdata)
{DOU_NODE *ptmp = plist->phead;while(ptmp != NULL){if(!memcmp(&ptmp->data, &olddata, sizeof(olddata))){ptmp->data = newdata;return 0;}ptmp = ptmp->pnext;}return -1;
}

11. 双向链表的销毁:

void Destroy_Dou_Link(DOU_LIST *plist)
{while(plist->phead != NULL){Pop_Head_Dou_Link(plist);}free(plist);return;
}

12. 双向链表删除某个结点:

int Delete_Data(DOU_LIST *plist, void *data, int (*pfun)(DOU_NODE *, void *))
{if(Is_Empty_Link(plist)){return 0;}DOU_NODE *pfree = plist->phead;while(pfree != NULL){if(pfun(pfree, data)){if(pfree == plist->phead){plist->phead = pfree->pnext;pfree->pnext->ppre = NULL;free(pfree);}else if(pfree->pnext == NULL){pfree->ppre->pnext = NULL;free(pfree);}else{pfree->ppre->pnext = pfree->pnext;pfree->pnext->ppre = pfree->ppre;free(pfree);}plist->curlen--;return 0;}else{pfree = pfree->pnext;}}return -1;
}

13. 双向链表逆序:

int Reverse_Dou_Link(DOU_LIST *plist)
{if(Is_Empty_Link(plist)){return 0;}DOU_NODE *ptmp = plist->phead->pnext;DOU_NODE *pinsert = NULL;plist->phead->pnext = NULL;while(ptmp != NULL){pinsert = ptmp;ptmp = ptmp->pnext;pinsert->ppre = NULL;pinsert->pnext = plist->phead;plist->phead->ppre = pinsert;plist->phead = pinsert;}return 0;
}

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

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

相关文章

SystemC入门学习Demo用例的工程化配置

背景:对不同的用例文件,使用CMakeLists.txt进行工程化管理的演示,这样开发者可以更加关注在代码开发上。 1,首先安装好系统环境的systemC库:ubuntu系统安装systemc-2.3.4流程-CSDN博客 2,准备好一个demo用…

再续前缘——C++【入门】

目录 1. 引用 引用概念 使用场景 1. 做参数 2. 引用做返回值 3.传值、传引用效率比较 4. 引用和指针的不同点 2. 内联函数 3.auto关键字 推导应用场景 auto不能推导的场景 4.基于范围的for循环(C11) 5.指针空值nullptr(C11) 1. 引用 引用概念 引用不是新定义一个…

JUC:手写实现一个简易的线程池(Java)

目录 ​编辑 先上完整代码: 解析: 任务队列: 线程池类: 拒绝策略: 先上完整代码: public class MyThreadPool {public static void main(String[] args) {ThreadPool threadPool new ThreadPool(2, …

Linux进程状态深度解析:探索进程的生命周期

文章目录 一、引言1、进程的概念与重要性2、Linux系统下进程状态的意义3、进程状态与系统性能的关系 二、Linux下进程状态概述1、Linux进程状态的分类2、进程状态信息的获取方法 三、Linux下进程状态详解1、运行状态(Running)2、可中断睡眠状态&#xff…

27.WEB渗透测试-数据传输与加解密(1)

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 内容参考于: 易锦网校会员专享课 上一个内容:26.WEB渗透测试-BurpSuite(五) BP抓包网站网址:http:…

实现Hello Qt 程序

🐌博主主页:🐌​倔强的大蜗牛🐌​ 📚专栏分类:QT❤️感谢大家点赞👍收藏⭐评论✍️ 目录 一、使用 "按钮" 实现 1、纯代码方式实现 2、可视化操作实现 (1&#xff09…

【leetcode面试经典150题】15.分发糖果(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主,题解使用C语言。(若有使用其他语言的同学也可了解题解思路,本质上语法内容一致&…

Hive3.0.0建库表命令测试

Hive创建表格格式如下: create [external] table [if not exists] table_name [(col_name data_type [comment col_comment],)] [comment table_comment] [partitioned by(col_name data_type [comment col_comment],)] [clustered by (col_name,col_name,...)…

贪心算法Java实现

贪心算法Java实现 贪心算法介绍 贪心算法(贪婪算法)是一个遵循启发式解决问题的算法范式,核心思想是通过在每一步的选择中都选用当前步骤下最优的选择,期望结果是最优的算法。贪心算法得到的结果不一定是最优结果,但是…

如何使用亮数据的数据IP代理及数据工具采集市场情报

如何使用亮数据的数据IP代理及数据工具采集市场情报 亮数据为粉丝提供了10美金的抵用券,成功注册账户,并登录后在用户界面里输入折扣代码即可享受抵扣! 折扣代码:zhouzhou 访问页面:https://www.bright.cn/proxy-types…

对抗样本攻击

对抗样本是指经过特殊设计或调整的输入数据,旨在欺骗人工智能模型,使其产生错误的预测或输出。对抗样本通常是通过对原始输入进行微小但精心计算的改变,使得模型产生意外的结果。这种模糊化的输入可能难以从人类角度甄别,但对机器…

Laravel 开发Api规范

一,修改时区 配置 config/app.php 文件 // 时区修改,感觉两者皆可,自己根据实际情况定义 timezone > PRC, // 大陆时间二,设置 Accept 头中间件 accept头即为客户端请求头,做成中间件来使用。Accept 决定了响应返…

gma 教程:计算标准化降水指数(SPI)

安装 gma:pip install gma (依赖的 gdal 需自行安装) 本文基于:gma 2.0.8,Python 3.10 本文用到数据请从 gma 网站获取:https://gma.luosgeo.com/UserGuide/climet/Index/SPI.html 。 SPEI 函数简介 gma.c…

c#编程基础学习之方法

目录 C#方法方法参数默认参数值多个参数返回值命名参数 方法重载 C#方法 实例 在程序类内创建一个方法: class Program {static void MyMethod() //static 静态意味着方法属于程序类,而不是程序类的对象。void 表示此方法没有返回值。MyMethod() 是方法…

比较720组结构数列的收敛过程

在行,列可自由变换的平面上3点结构只有6个 这次计算由这6个结构排列组合,构成的所有720个不重复数列的递推收敛过程。 结果表明,所有的数列都可以在有限步内收敛。 有461个数列在3-4-3的递推过程中是天然稳定的,收敛结果就是本身…

上海计算机学会 2024年3月月赛 丙组T1 最近的数字(数学)

第一题:T1最近的数字 标签:数学题意:给定两个正整数 n n n与 d d d,请找到所有最接近 n n n且是 d d d的倍数的整数。如果有多个数字满足要求,从小到大输出。数据范围: 1 ≤ n , d ≤ 1 , 000 , 000 , 000…

STM32学习和实践笔记(4):分析和理解GPIO_InitTypeDef GPIO_InitStructure (c)

第二个成员变量是GPIOSpeed_TypeDef GPIO_Speed;也与int a一样同理。 GPIOSpeed_TypeDef是一个枚举类型,其定义如下: typedef enum { GPIO_Speed_10MHz 1, GPIO_Speed_2MHz, GPIO_Speed_50MHz }GPIOSpeed_TypeDef; #define IS_GPI…

.NET Standard、.NET Framework 、.NET Core三者的关系与区别?

.NET Standard、.NET Framework 和 .NET Core 是 .NET 平台生态中的三个关键概念,它们之间存在明确的关系和显著的区别。下面分别阐述它们各自的角色以及相互间的关系: .NET Standard 角色: .NET Standard 是一套正式的 API 规范&#xff0c…

项目经理常用的工具模型有哪些?

项目经理常用的工具模型包括但不限于以下几种: 甘特图:这是一种将大型项目划分为几个阶段,并展示项目进度的工具。在甘特图中,可以清晰地看到每个任务的开始和结束时间,以及任务之间的依赖关系。 工作分解结构&#…

Leetcode刷题-哈希表详细总结(Java)

哈希表 当我们想使⽤哈希法来解决问题的时候,我们⼀般会选择如下三种数据结构。 数组set (集合)map(映射) 当我们遇到了要快速判断⼀个元素是否出现集合⾥的时候,就要考虑哈希法。如果在做⾯试题⽬的时候…