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

自学嵌入式 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)复杂编译设置

相关文章:

  • Keil软件中STM32(ARM)与C51兼容方法
  • STM32--串口函数
  • 优化Hadoop性能:如何修改Block块大小
  • AWS CodePipeline+ Elastic Beanstalk(AWS中国云CI/CD)
  • html+css+js趣味小游戏~记忆卡片配对(附源码)
  • c语言- 如何构建CMake项目(Linux/VSCode)
  • 去中心化算力池:基于IPFS+智能合约的跨校GPU资源共享平台设计
  • 零基础设计模式——创建型模式 - 工厂方法模式
  • 电商运营数据分析指南之流量指标
  • <uniapp><vuex><状态管理>在uniapp中,如何使用vuex实现数据共享与传递?
  • uni-app 中使用 mumu模拟器 进行调试和运行详细教程
  • 青少年编程与数学 02-019 Rust 编程基础 20课题、面向对象
  • idea查看class文件源码
  • Electron+vite+vue3 从0到1搭建项目,开发Win、Mac客户端
  • 青少年编程与数学 02-019 Rust 编程基础 19课题、项目发布
  • CodeBuddy全新升级:体验Craft智能体的对话式编程革命
  • iOS苹果和Android安卓测试APP应用程序的区别差异
  • Java虚拟机 - 程序计数器和虚拟机栈
  • Ubuntu 22.04安装zabbix7.0.0图形中文乱码
  • 开源CMS系统中哪些常见的安全漏洞最需要注意?
  • 人民日报今日谈:科技赋能,继续把制造业搞好
  • 全国首例闭环脊髓神经接口手术在浙江完成,截瘫患者实现自主行走
  • 钟南山谈新冠阳性率升高:可防可治不用慌,高危人群应重点关注
  • 甘肃省白银市一煤矿发生透水事故,3人失联
  • 媒体:多家国有大行存款利率即将迎来新一轮下调
  • 总书记回信二周年之际,上海如何将垃圾分类深度融入城市发展?