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

【学习嵌入式day-18-数据结构-循环链表】

循环链表

特点:

头节点的ppre指向链表最后一个节点

最后一个节点的ppre指向第一个节点

节点定义

//节点存放的数据类型
typedef int datatype;
//节点类型
typedef struct  node{datatype data;struct node *ppre;struct node *pnext;
}linknode;

链表创建

申请节点

pnext和ppre都指向自己

需要返回linknode *型的指针

//创建空链表
linknode *create_empty_linklist(void)
{linknode *ptmpnode = NULL;ptmpnode = malloc(sizeof(linknode));if(NULL == ptmpnode){perror("fail to malloc");return NULL;}ptmpnode->pnext = ptmpnode->ppre = ptmpnode;return ptmpnode;
}

头插法

(不需要区别第一次插入,每次插入都是一样步骤)

1、申请空间

2、存放数据ptmpnode->data = tmpdata

3、将pnext赋值为头节点的pnext,使申请的节点指向头节点ptmpnode->pnext = phead->pnext

4、将ppre指向头节点ptmpnode->ppre = phead

5、头节点的pnext指向新申请的节点phead->pnext = ptmpnode

6、将后续申请节点的ppre指向新申请的节点ptmpnode->pnext->ppre= ptmpnode

//头插法
int insert_head_linklist(linknode *phead, datatype tmpdata)
{linknode *ptmpnode = NULL;ptmpnode = malloc(sizeof(linknode));if(NULL == ptmpnode){perror("fail to malloc");return -1;}ptmpnode->data = tmpdata;           //存放数据ptmpnode->pnext = phead->pnext;     //将新申请的pnext赋值为头节点的pnext,使申请的节点指向头节点ptmpnode->ppre = phead;             //将新申请的ppre指向头结点ptmpnode->ppre->pnext = ptmpnode;   //前一个节点的pnext指向自己// phead->pnext = ptmpnode;            //头结点的pnext指向新申请的节点ptmpnode->pnext->ppre = ptmpnode;   //后一个节点的ppre指向自己//   ptmpnode->pnext->ppre = ptmpnode;   //将后续申请节点的ppre指向新申请的节点return 0;
}

尾插法

1、申请空间

2、存放数据     ptmpnode->data = tmpdata

3、将新申请的节点pnext赋值为头节点  ptmpnode->pnext = phead

4、将新申请的节点ppre赋值为之前的最后一个节点ptmpnode->ppre = phead->ppre(之前的最后一个节点)

5、将之前最后 一个节点的pnext指向新申请节点phead->ppre->pnext = ptmpnode

6、将头节点的ppre指向新申请的节点phead->ppre = ptmpnode

//尾插法
int insert_tail_linklist(linknode *phead, datatype tmpdata)
{linknode *ptmpnode = NULL;ptmpnode = malloc(sizeof(linknode));if(NULL == ptmpnode){perror("farl to malloc");return -1;}ptmpnode->data = tmpdata;       //存放数据ptmpnode->pnext = phead;        //将新申请的节点pnext赋值为头节点ptmpnode->ppre = phead->ppre;   //将新申请的节点ppre赋值为之前的最后一个节点ptmpnode->pnext->ppre = ptmpnode;   //后一个节点的ppre指向自己ptmpnode->ppre->pnext = ptmpnode;   //前一个节点的pnext指向自己return 0;
}

遍历

1、指针指向第一个有效节点

2、指针不等于头节点时,进入循环遍历

循环链表最终循环条件由不等于NULL,改为不等于头节点

//遍历
int show_linklist(linknode *phead)
{linknode *ptmpnode = NULL;ptmpnode = phead->pnext;        //将ptmp指针指向第一个有效节点while(ptmpnode != phead)        //ptmp指针不等于头结点时进入循环{printf("%d ", ptmpnode->data);ptmpnode = ptmpnode->pnext; //指针向后走}printf("\n");return 0;
}

查找指定元素

定义一个指针ptmp指向第一个有效节点

当ptmp不等于头结点时,进入循环,if语句判断是否找到指定元素,找到了就返回当前指针

没有找到ptmp指针继续往后走

最后循环结束还没有找到就返回NULL

//查找
linknode *find_linklist(linknode *phead, datatype tmpdata)
{linknode *ptmpnode = NULL;ptmpnode = phead->pnext;        //将ptmp指针指向第一个有效节点while(ptmpnode != phead)        //ptmp指针不等于头结点时进入循环{if(ptmpnode->data == tmpdata)//判断是否找到指定元素{return ptmpnode;        //找到,返回当前指针}ptmpnode = ptmpnode->pnext; //没找到,指针继续向后走}return NULL;                    //循环完成还没找到,返回NULL
}

修改

定义一个指针ptmp指向第一个有效节点

当ptmp不等于头结点时,进入循环,if语句判断是否找到指定元素,找到了就更换为新值

没有找到ptmp指针继续往后走

最后返回0

//修改
int update_linklist(linknode *phead, datatype olddata, datatype newdata)
{linknode *ptmpnode = NULL;ptmpnode = phead->pnext;        //ptmp指针指向第一个有效节点while(ptmpnode != phead)        //ptmp不等于头结点进入循环{if(ptmpnode->data == olddata)   //判断是否遇到olddata{ptmpnode->data = newdata;   //将旧值更新为新值}ptmpnode = ptmpnode->pnext;     //没找到旧值,ptmp指针继续向后走}return 0;
}

删除指定元素

定义两个指针,ptmp指向第一个有效节点,一个释放指针pfree

当ptmp不等于头指针时,进入循环,if语句判断是否找到指定元素,找到了:前一个节点的pnext指向后一个节点,后一个节点的ppre指向前一个节点,pfree指针赋值为ptmp指针,让ptmp向后走一步,释放掉pfree指针所指向的空间。

没有找到指定元素,ptmp向后走继续找

//删除指定元素
int delete_linklist(linknode *phead, datatype tmpdata)
{linknode *ptmpnode = NULL;linknode *pfreenode = NULL;ptmpnode = phead->pnext;    //ptmp指针指向第一个有效节点while(ptmpnode != phead){if(ptmpnode->data == tmpdata){ptmpnode->ppre->pnext = ptmpnode->pnext; //前一个节点的pnext指向后一个节点ptmpnode->pnext->ppre = ptmpnode->ppre;  //后一个节点的ppre指向前一个节点pfreenode = ptmpnode;                    //pfree指针跟着ptmp指针ptmpnode = ptmpnode->pnext;              //ptmp指针向后走free(pfreenode);                         //释放掉pfree所指的空间}else                                         //没有找到要删除的元素,指针ptmp向后走{ptmpnode = ptmpnode->pnext;}}return 0;
}

销毁所有元素

使用二级指针。

定义两个指针,ptmp指向第一个有效节点,pfree指向ptmp,当ptmp不等于头指针时,ptmp向后走,释放掉free指针指向的空间,pfree指向ptmp

循环结束,释放掉头指针,头指针清零,返回0

//销毁
int destory_linklist(linknode **pphead)
{linknode *ptmpnode = NULL;linknode *pfreenode = NULL;ptmpnode = (*pphead)->pnext;       //指针指向第一个有效节点pfreenode = ptmpnode;               //pfree指针指向ptmpwhile(ptmpnode != *pphead)          //ptmp不等于头指针时,进入循环{ptmpnode = ptmpnode->pnext;     //ptmp指针向后走free(pfreenode);                //释放pfree指针pfreenode = ptmpnode;           //pfree走到ptmp指针的位置}free(*pphead);                      //释放头指针*pphead = NULL;                     //头指针清零return 0;
}

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

相关文章:

  • 代码随想录day57图论7
  • CodeBuddy IDE 使用测评——半小时做一个web可视化数据工具
  • 基于WOA鲸鱼优化的VMD-GRU时间序列预测算法matlab仿真
  • uniapp 类似popover气泡下拉框组件
  • LeetCode——2683. 相邻值的按位异或
  • Spring Boot 与 Ollama 集成部署私有LLM服务 的完整避坑指南,涵盖 环境配置、模型管理、性能优化 和 安全加固
  • 【Electron】electron-vite中基于electron-builder与electron-updater实现程序远程自动更新,附源码
  • 对于包含大量文件的程序的便捷makefile操作
  • 建筑地产安全监控误报率↓77%:陌讯多模态融合算法实战解析
  • 布控球是什么?布控球有什么作用?什么场景下会使用到布控球设备?一篇短文带你了解
  • Windows驱动更新下载工具,电脑硬件设备驱动程序自动安装下载更新,可备份还原!键盘鼠标声卡网卡显卡主板硬盘驱动都可以下载,免费使用的神器!
  • 【软考中级网络工程师】2021年下半年上午真题及答案解析
  • 【科研绘图系列】R语言绘制误差棒图
  • C++继承关系中,深度解析类内存布局与多态的实现
  • PDF 文本提取技术深度对比:基于规则与基于模型的两种实现
  • 【乐企板式文件生成工程】关于乐企板式文件(PDF/OFD/XML)生成工程介绍
  • 结合opencv解释图像处理中的结构元素(Structuring Element)
  • C语言的结构体与联合体
  • 通信算法之301:IP核之单双端口 RAM和FIFO 读写
  • 【设计模式】代理模式
  • 【HUST】计算机|大学计算机基础内容(纯科普向)+数据结构数组、树、队列【旧文搬运】
  • Mac上pnpm的安装与使用
  • Java技术栈/面试题合集(12)-Maven篇
  • 使用maven-shade-plugin解决es跨版本冲突
  • ApplicationContext的实现类有哪些?
  • JSqlParser学习笔记 快速使用JSqlParser
  • C++临时对象:来源与性能优化之道
  • mysql 数据库系统坏了,物理拷贝出数据怎么读取
  • 【机器学习】(算法优化一)集成学习之:装袋算法(Bagging):装袋决策树、随机森林、极端随机树
  • Day31:文件的规范拆分与写法