当前位置: 首页 > web >正文

自学嵌入式 day21 - 数据结构 双向链表

1.双向链表

2.基础操作

(1)头部插入

int InsertHeadDouLinkList(DouLinkList *dl,DATATYPE *data)
{
    DouLinkNode *newnode = (DouLinkNode *)malloc(sizeof(DouLinkNode));//定义新节点来存储需插入的数据
        if(NULL == newnode)//判断结点空间是否申请成功
        {
          fprintf(stderr,"intertHeadDouLinkList malloc");
          return 1;
        }
    memcpy(&newnode -> data,data,sizeof(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 ShowDouLinkList(DouLinkList *dl,DIR dir) 
{
    if(FORWADR == dir)//正向打印
    {
        DouLinkNode *tmp = dl -> head;
        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)//反向打印,从末尾开始向前打印
    {
        DouLinkNode *tmp = dl -> head;
        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;
        }
    }
}

(3)尾部插入

int IsEmptyLinkList(DouLinkList *dl)
{
    return 0 == dl -> clen;
}

int InsertTaiDouLinkList(DouLinkList *dl,DATATYPE *data)
{
    if(IsEmptyLinkList(dl))//判断链表是否为空
    {
        return InsertHeadDouLinkList(dl,data);
    }
    else 
    {
        DouLinkNode *newnode = malloc(sizeof(DouLinkNode));//申请新结点存储待插入数据
        if(NULL == newnode)//判断新结点空间是否申请成功
        {
            fprintf(stderr,"insertTaiDouLinkList malloc\n");
            return 1;
        }
        memcpy(&newnode -> data,data,sizeof(DATATYPE));//存入待插入数据
        newnode -> next = NULL;//初始化新结点指针
        newnode -> prev = NULL;
        DouLinkNode *tmp = dl -> head;//定义新指针,指向头指针
        while(tmp -> next)//遍历链表
        {
            tmp = tmp -> next;
        }
        newnode -> prev = tmp;//将新结点插入链表尾部
        tmp -> next = newnode;
        dl -> clen++;    
    }
    return 0;
}

(4)指定位置插入

int GetsizeofDouLinkList(DouLinkList *dl)
{
    return dl -> clen;
}

int InsertPosDouLinkList(DouLinkList *dl,DATATYPE *data,int pos)
{
    int len = GetsizeofDouLinkList(dl);//算出链表长度
    if(0 == pos)//头部插入
    {
        return InsertHeadDouLinkList(dl,data);
    }
    else if(pos == len)//尾部插入
    {
        return InsertTaiDouLinkList(dl,data);
    }
    else
    {
        DouLinkNode *newnode = malloc(sizeof(DouLinkNode));
        if(NULL == newnode)
        {
            fprintf(stderr,"InsertPosDouLinkList malloc\n");
            return 1;
        }
        memcpy(&newnode -> data,data,sizeof(DATATYPE));
        newnode -> next = NULL;
        newnode -> prev = NULL;
        DouLinkNode *tmp = dl -> head;
        for(int 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;
}

(5)查找

DouLinkNode *FindDouLinkList(DouLinkList *dl,char *name)
{
    int len = GetsizeofDouLinkList(dl);//获取链表长度
    DouLinkNode *tmp = dl -> head;//定义新指针,指向头指针
    for(int i = 0;i < len;++i)//遍历链表
    {
        if(0 == strcmp(tmp -> data.name,name))//用已给name查找结点
        {
            return tmp;
        }
        tmp = tmp -> next;
    }
    return NULL;
}

(6)替换

int ModifyDouLinkLinst(DouLinkList *dl,char *name,DATATYPE *data)
{
    DouLinkNode *ret = FindDouLinkList(dl,name);//查找结点
    if(NULL == ret)//判断是否找到结点
    {
        return 1;
    }
    memcpy(&ret -> data,data,sizeof(DATATYPE));//替换数据
    return 0;
}

练习:

(1)销毁

int DestroyDouLinkList(struct DouLinkList* dl)
{
    DouLinkNode *tmp = dl -> head;//定义新指针,指向头指针
    DouLinkNode *ret ;
    while(tmp)//遍历链表
    {
        ret = tmp;
        tmp = tmp -> next;
        free(ret);//释放结点空间
        ret = NULL;
    }
    free(dl);
    dl = NULL;
    return 0;

}

(2)删除

int DeleteDouLinkList(struct DouLinkList* dl,char* name)
{
    DouLinkNode *tmp = FindDouLinkList(dl,name);//查找待删结点
    if(NULL == tmp -> prev)//头删
    {
        dl -> head = tmp -> next;
        tmp -> next -> prev = NULL;
        dl -> clen--;
        free(tmp);
        tmp = NULL;
        return 0;
    }
    else if(NULL == tmp -> next)//尾删
    {
        tmp -> prev -> next = NULL;
        dl -> clen--;
        free(tmp);
        tmp = NULL;
        return 0;
    }
    else 
    {
        tmp -> prev ->next = tmp -> next;
        tmp -> next ->prev = tmp -> prev;
        dl -> clen--;
        free(tmp);
        tmp = NULL;
        return 0;
    }
}

(3)逆序

int RevertDouLinkList(struct DouLinkList* dl)
{
    DouLinkNode *p = NULL;//定义一个指向被逆转结点的指针,初始位空指针
    DouLinkNode *tmp = dl -> head;//定义一个指向待逆转结点的指针,初始化位头指针
    DouLinkNode *n = tmp ->next;//定义一个指向待逆转结点next的指针,辅助遍历链表
    int len = GetsizeofDouLinkList(dl);
    if(len < 2)//逆序链表长度必须大于1
    {
        return 1;
    }
    while(1)
    {
        tmp -> next = p;//将待逆序结点指向被逆序节点
        tmp -> prev = n;

        p = tmp;//p++
        tmp = n;//tmp++
        if(NULL == tmp)//判断指针是否为空
        {
            break;//指针为空时结束循环
        }
        n = n -> next;//n++

    }
    dl -> head = p;//将头指针指向已逆序后的链表首位
    return 0;
}

注:

1.Makefile: vi Makefile

自动指定编译

(1)简单编译设置

(2)复杂编译设置

http://www.xdnf.cn/news/7560.html

相关文章:

  • 全局对比度调整
  • MCP 协议传输机制大变身:抛弃 SSE,投入 Streamable HTTP 的怀抱
  • taro 小程序 CoverImage Image src无法显示图片的问题
  • 剧本杀小程序:指尖上的沉浸式推理宇宙
  • 【Linux笔记】——线程同步信号量与环形队列生产者消费者模型的实现(PV操作)
  • shp2pgsql 导入 Shp 到 PostGIS 空间数据库
  • MATLAB中进行语音信号分析
  • Kotlin 协程 (一)
  • 对冲策略加仓止损盈思路
  • 数组的概述
  • 反射在spring boot自动配置的应用
  • Mysql 中的日期时间函数汇总
  • 2025ICPC南昌邀请赛题解
  • 基于规则引擎与机器学习的智能Web应用防火墙设计与实现
  • 【数据库课程设计】网上投票管理系统
  • 阿博图书馆管理系统 Java+Spring Boot+MySQL 实战项目分享
  • leetcode hot100:一、解题思路大全:技巧(只出现一次的数字、多数元素、颜色分类、下一个排列、寻找重复数)、矩阵(矩阵置零、螺旋矩阵、旋转图像、搜索二维矩阵Ⅱ)
  • ArkUI Tab组件开发深度解析与应用指南
  • setInterval和setTimeout的区别是什么
  • 【java第18集】java引用数据类型详解
  • Q-learning 算法学习
  • JUC入门(三)
  • FAL API分析
  • 工会考试怎么备考
  • 如何确保低空经济中的数据安全?
  • 斜齿轮直列齿轮箱市场分析报告:驱动因素、挑战及前景预测
  • WAF深度解析:精准适配六大核心业务场景
  • Python实现的在线词典学习工具
  • JQuery 禁止页面滚动(防止页面抖动)
  • 测试开发面试题:Python高级特性通俗讲解与实战解析