嵌入式学习笔记 D21:双向链表的基本操作

news2025/5/16 14:12:35
  • 双向链表的定义与创建
  • 双向链表的插入
  • 双向链表的查找
  • 双向链表的修改
  • 双向链表的删除
  • 双向链表的逆序
  • 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 dian
        memcpy(&newnode->data,data,sizeof(struct DATATYPE));
        newnode->next = NULL;
        newnode->prev = NULL;
        // lian jie lian biao
        newnode->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 dian
        memcpy(&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)
 

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

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

相关文章

让AI帮我写一个word转pdf的工具

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

OrangePi Zero 3学习笔记(Android篇)10 - SPI和从设备

目录 1. 配置内核 2. 修改设备数 3. 修改权限 4. 验证 Zero 3的板子有2个SPI Master接口&#xff0c;其中SPI0接的是板载16MB大小的SPI Nor Flash&#xff0c;SPI1则是导出到26pin的接口上。 spi和i2c有点不同&#xff0c;spi是直接生成spi虚拟设备&#xff0c;所以在dev里…

基于策略的强化学习方法之近端策略优化(PPO)深度解析

PPO&#xff08;Proximal Policy Optimization&#xff09;是一种基于策略梯度的强化学习算法&#xff0c;旨在通过限制策略更新幅度来提升训练稳定性。传统策略梯度方法&#xff08;如REINFORCE&#xff09;直接优化策略参数&#xff0c;但易因更新步长过大导致性能震荡或崩溃…

文章复现|(1)整合scRNA-seq 和空间转录组学揭示了子宫内膜癌中 MDK-NCL 依赖性免疫抑制环境

https://www.frontiersin.org/journals/immunology/articles/10.3389/fimmu.2023.1145300/full 目标&#xff1a;肿瘤微环境(TME)在子宫内膜癌(EC)的进展中起着重要作用。我们旨在评估EC的TME中的细胞群体。 方法&#xff1a;我们从GEO下载了EC的单细胞RNA测序(scRNA-seq)和空…

HTML-3.4 表单form

本系列可作为前端学习系列的笔记&#xff0c;代码的运行环境是在HBuilder中&#xff0c;小编会将代码复制下来&#xff0c;大家复制下来就可以练习了&#xff0c;方便大家学习。 系列文章目录 HTML-1.1 文本字体样式-字体设置、分割线、段落标签、段内回车以及特殊符号 HTML…

【MySQL】服务器配置与管理(相关日志)

&#x1f525;个人主页&#xff1a; 中草药 &#x1f525;专栏&#xff1a;【MySQL】探秘&#xff1a;数据库世界的瑞士军刀 一、系统变量和选项 当通过mysqld启动数据库服务器时&#xff0c;可以通过选项文件或命令行中提供选项。一般&#xff0c;为了确保服务器在每次运行时…

【问题】Watt加速github访问速度:好用[特殊字符]

前言 GitHub 是全球知名的代码托管平台&#xff0c;主要用于软件开发&#xff0c;提供 Git 仓库托管、协作工具等功能&#xff0c;经常要用到&#xff0c;但是国内用户常因网络问题难以稳定访问 。 Watt Toolkit&#xff08;原名 Steam&#xff09;是由江苏蒸汽凡星科技有限公…

vue3:十三、分类管理-表格--行内按钮---行删除、批量删除实现功能实现

一、实现效果 增加行内按钮的样式效果,并且可以根绝父组件决定是否显示 增加行内删除功能、批量删除功能 二、增加行内按钮样式 1、增加视图层按钮 由于多个表格都含有按钮功能,所以这里直接在子组件中加入插槽按钮 首先增加表格行<el-table-column></el-table-…

浏览器设置代理ip后不能上网?浏览器如何改ip地址教程

使用代理IP已成为许多用户保护隐私、绕过地域限制或进行网络测试的常见做法。当浏览器设置代理IP后无法上网时&#xff0c;通常是由于代理配置问题或代理服务器本身不可用。以下是排查和解决问题的详细步骤&#xff0c;以及更改浏览器IP的方法&#xff1a; 一、代理设置后无法上…

R语言的专业网站top5推荐

李升伟 以下是学习R语言的五个顶级专业网站推荐&#xff0c;涵盖教程、社区、资源库和最新动态&#xff1a; 1.R项目官网 (r-project.org) R语言的官方网站&#xff0c;提供软件下载、文档、手册和常见问题解答。特别适合初学者和高级用户&#xff0c;是获取R语言核心资源的…

[训练和优化] 3. 模型优化

&#x1f44b; 你好&#xff01;这里有实用干货与深度分享✨✨ 若有帮助&#xff0c;欢迎&#xff1a;​ &#x1f44d; 点赞 | ⭐ 收藏 | &#x1f4ac; 评论 | ➕ 关注 &#xff0c;解锁更多精彩&#xff01;​ &#x1f4c1; 收藏专栏即可第一时间获取最新推送&#x1f514;…

无人设备遥控器之无线通讯技术篇

无人设备遥控器的无线通讯技术是确保遥控操作准确、稳定、高效进行的关键。以下是对无人设备遥控器无线通讯技术的详细解析&#xff1a; 一、主要无线通讯技术类型 Wi-Fi通讯技术 原理&#xff1a;基于IEEE 802.11标准&#xff0c;通过无线接入点&#xff08;AP&#xff09;…

PyTorch LSTM练习案例:股票成交量趋势预测

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

CK3588下安装linuxdeployqt qt6 arm64

参考资料&#xff1a; Linux —— linuxdeployqt源码编译与打包&#xff08;含出错解决&#xff09; linux cp指令报错&#xff1a;cp: -r not specified&#xff1b; cp: omitting directory ‘xxx‘&#xff08;需要加-r递归拷贝&#xff09; CMake Error at /usr/lib/x86_64…

木马查杀引擎—关键流程图

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

二程运输的干散货船路径优化

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

华为数字政府与数字城市售前高级专家认证介绍

华为数字政府与数字城市售前高级专家认证面向华为合作伙伴售前高级解决方案专家、华为数字政府与数字城市行业解决方案经理&#xff08;VSE&#xff09;。 通过认证验证的能力 您将了解数字政府、数字城市行业基础知识&#xff0c;了解该领域内的重点场景&#xff1b;将对华…

【docker】--容器管理

文章目录 容器重启--restart 参数选项及作用**对比 always 和 unless-stopped****如何查看容器的重启策略&#xff1f;** 容器重启 –restart 参数选项及作用 重启策略 no&#xff1a;不重启&#xff08;默认&#xff09;。on-failure&#xff1a;失败时重启&#xff08;可限…

基于OpenCV的人脸微笑检测实现

文章目录 引言一、技术原理二、代码实现2.1 关键代码解析2.1.1 模型加载2.1.2 图像翻转2.1.3 人脸检测 微笑检测 2.2 显示效果 三、参数调优建议四、总结 引言 在计算机视觉领域&#xff0c;人脸检测和表情识别一直是热门的研究方向。今天我将分享一个使用Python和OpenCV实现…

2025-5-15Vue3快速上手

1、setup和选项式API之间的关系 (1)vue2中的data,methods可以与vue3的setup共存 &#xff08;2&#xff09;vue2中的data可以用this读取setup中的数据&#xff0c;但是反过来不行&#xff0c;因为setup中的this是undefined &#xff08;3&#xff09;不建议vue2和vue3的语法混用…