【数据结构】-- 单链表 vs 双向链表
🌈 个人主页:白子寰
🔥 分类专栏:python从入门到精通,魔法指针,进阶C++,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~
💡 坚持创作博文(平均质量分82+),分享更多关于深度学习、C/C++,python领域的优质内容!(希望得到您的关注~)
目录
单链表和双向链表的比较
链表的打印
单链表
双向链表
初始化
双向链表
开辟空间,写入新数据
单链表
双向链表
尾部插入数据
单链表
双向链表
头部插入数据
单链表
双向链表
尾部删除数据
单链表
双向链表
头部删除数据
单链表
双向链表
查找
单链表
双向链表
在指定位置之前插入数据
单链表
在指定位置之后插入数据
单链表
双向链表
删除指定位置数据
单链表
双向链表
删除指定位置后的数据
单链表
销毁链表
单链表
双向链表
单链表和双向链表的比较
单向链表 | 双向链表 | |
指代不同 | 链表的链接方向是单向的,访问链表时时要顺序读取从头开始访问 | 每个数据的节点都有两个指针,即直接前驱和直接后驱 |
优点不同 | 单个节点创建方便,普通的线性内存通常在创建的时候就需要设定数据的大小,节点的访问方便,可以通过循环/递归的方法访问到任意数据 | 从双向链表中的任意一个节点开始,方便访问前驱节点和后继节点 |
缺点不同 | 增加/删除节点复杂,需要多分配一个指针存储空间 | 平均访问效率低于线性表,只能从头到尾遍历,只能找到后继,无法找到前驱(只能前进) |
链表的打印
单链表
//链表的打印
void SLTPrint(SLTNode* phead)
{SLTNode* pcur = phead;while (pcur){printf("%d->", pcur->data);pcur = pcur->next;}printf("NULL\n");
}
双向链表
//打印
void LTPrint(LTNode* phead)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){printf("%d->", pcur->dada);pcur = pcur->next;}printf("\n");
}
初始化
双向链表
//双向链表初始化
LTNode* LTInit()
{//哨兵位设置为-1LTNode* phead = SLTBuyNode(-1);return phead;
}
开辟空间,写入新数据
单链表
//开辟空间,写入新数据
SLTNode* SLTbuyNode(SLTDatatype x)
{SLTNode* newnode = (SLTNode*)malloc(sizeof(SLTNode));if (newnode == NULL){perror("malloc");exit(1);}//先插入,后数据为空(后为空)newnode->data = x;newnode->next = NULL;return newnode;//返回数据
}
双向链表
//扩容,申请新节点
LTNode* SLTBuyNode(LTDataType x)
{LTNode* newnode = (LTNode*)malloc(sizeof(LTNode));//扩容if (newnode == NULL){perror("malloc");exit(1);}//数据赋值newnode->dada = x;//指向自己newnode->next = newnode->prev = newnode;return newnode;
}
尾部插入数据
单链表
//尾插
void SLTPushBack(SLTNode** pphead, SLTDatatype x)
{//传的参数不为空assert(pphead);SLTNode*newnode = SLTbuyNode(x);//链表为空,新节点作为phead//*pphead是指向第一个节点的指针if (*pphead == NULL)//头节点为空{*pphead = newnode;return;}//链表不为空,找尾节点//ptail作为尾节点SLTNode* ptail = *pphead;//先方向,后数据while (ptail->next){ptail = ptail->next;}ptail->next = newnode;
}
双向链表
//尾插
void LTPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = SLTBuyNode(x);newnode->next = phead;newnode->prev = phead->prev;phead->prev->next = newnode;phead->prev = newnode;
}
头部插入数据
单链表
//头插
void SLTPushFront(SLTNode** pphead, SLTDatatype x)
{//传参有效assert(pphead);//开辟空间,新数据进入SLTNode* newnode = SLTbuyNode(x);//先方向,后数据newnode->next = *pphead;*pphead = newnode;
}
双向链表
//头插
void LTPushFront(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = SLTBuyNode(x);newnode->next = phead->next;newnode->prev = phead;phead->next = newnode;phead->prev = newnode->prev->prev;
}
尾部删除数据
单链表
//尾删
void SLTPopBack(SLTNode** pphead)
{//保证传参数据有效assert(pphead);//链表不能为空assert(*pphead);//链表不为空//链表只有一个节点if ((*pphead)->next==NULL){free(*pphead);*pphead = NULL;return;}//有多个节点SLTNode* prev = NULL;SLTNode* ptail = *pphead;while (prev->next){prev = ptail;ptail = ptail->next;}prev = NULL;//销毁尾节点free(ptail);ptail = NULL;
}
双向链表
//尾删
void LTPopBack(LTNode* phead)
{assert(phead);LTNode* del = phead->prev;del->prev->next = phead;phead->prev = del->prev;free(del);del = NULL;
}
头部删除数据
单链表
//头删
void SLTPopFront(SLTNode** pphead)
{//保证传参有效assert(pphead);//保证链表有效assert(*pphead);//让第二个节点成为新的头SLTNode* next = (*pphead)->next;//把旧的头节点释放掉free(*pphead);*pphead = next;//第一个节点 = 原来第二个节点
}
双向链表
//头删
void LTPopFront(LTNode* phead)
{assert(phead);LTNode* del = phead->next;phead->next = del->next;del->next->prev = phead;free(del);del = NULL;
}
查找
单链表
SLTNode* SLTFind(SLTNode** pphead, SLTDatatype x)
{//保证传参有效assert(pphead);//遍历链表SLTNode* pcur = *pphead;while (pcur){if (pcur->data == x){return pcur;}pcur = pcur->next;}//没有找到return NULL;
}
双向链表
//查找
LTNode* LTFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* pcur = phead->next;while (pcur != phead){if (pcur->dada == x){return pcur;}pcur = pcur->next;}return NULL;
}
在指定位置之前插入数据
单链表
//在指定位置之前插入数据
void SLTInsert(SLTNode** pphead, SLTNode* pos, SLTDatatype x)
{//保证传参有效assert(pphead);//保证指定位置数据有效assert(pos);//链表也不能为空assert(*pphead);//新节点,开辟新空间SLTNode* newnode = SLTbuyNode(x);//pos刚好是头节点if (newnode->next = *pphead){//头插SLTPushFront(pphead, x);return;}//pos不是头节点的情况SLTNode* prev = *pphead;if (prev->next != pos){prev = prev->next;}prev->next = newnode;newnode->next = pos;
}
在指定位置之后插入数据
单链表
//在指定位置之后插入数据
void SLTInsertAfter(SLTNode* pos, SLTDatatype x)
{//保证目标数据有效assert(pos);//创建新节点SLTNode* newnode = SLTbuyNode(x);//先方向,后数据newnode->next = pos->next;pos->next = newnode;
}
双向链表
//在pos位置之后插入数据
void LTInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* newnode = SLTBuyNode(x);newnode->prev = pos;newnode->next = pos->next;pos->next = newnode;pos->next->prev = newnode;
}
删除指定位置数据
单链表
//删除pos节点
void SLTErase(SLTNode** pphead, SLTNode* pos)
{//保证传的参数有效assert(pphead);//保证单链表有效assert(*pphead);//保证目标数据有效assert(pos);//pos刚好是头节点,没有前驱节点if (*pphead == pos){//头删SLTPopFront(pphead);return;}//pos不是头节点SLTNode* prev = *pphead;while (prev->next != pos){prev = prev->next;}//释放prev->next = pos->next;free(pos);pos = NULL;
}
双向链表
//删除pos位置的数据
void LTErase(LTNode* pos)
{assert(pos);LTNode* del = pos;pos->prev->next = pos->next;pos->next->prev = pos->prev;free(del);del = NULL;
}
删除指定位置后的数据
单链表
//删除pos之后的节点
void SLTEraseAfter(SLTNode* pos)
{//保证目标数据有效assert(pos);//pos->next数据有效assert(pos->next);SLTNode* del = pos->next;pos->next = pos->next->next;//释放free(del);del = NULL;
}
销毁链表
单链表
//销毁链表
void SListDesTroy(SLTNode** pphead)
{//保证传的参数有效assert(pphead);//保证链表有效assert(*pphead);SLTNode* pcur = *pphead;while (pcur){SLTNode* next = pcur->next;free(pcur);pcur = next;}*pphead = NULL;
}
双向链表
//销毁
void LTDesTroy(LTNode* phead)
{//哨兵位不能为空assert(phead);LTNode* pcur = phead->next;while(pcur != phead){LTNode* next = pcur->next;free(pcur);pcur = next;}free(phead);phead = NULL;
}
***********************************************************分割线*****************************************************************************
完结!!!
感谢浏览和阅读。
等等等等一下,分享最近喜欢的一句话:“成为正确答案的第一步,相信自己会是正确答案”。
我是白子寰,如果你喜欢我的作品,不妨你留个点赞+关注让我知道你曾来过。
你的点赞和关注是我持续写作的动力!!!
好了划走吧。
相关文章:

【数据结构】-- 单链表 vs 双向链表
🌈 个人主页:白子寰 🔥 分类专栏:python从入门到精通,魔法指针,进阶C,C语言,C语言题集,C语言实现游戏👈 希望得到您的订阅和支持~ 💡 坚持创作博文…...

暴雨孙辉:做好服务器,但更要辟出技术落地之道
稳扎稳打一直是暴雨的风格,这在被访者孙辉的身上尽显。作为暴雨(武汉暴雨信息发展有限公司)中国区销售及市场副总裁,在谈及公司的技术发展与市场推广走势之时,孙辉沉稳、敏锐且逻辑清晰。 因在服务器领域起步很早&…...

天地人和•大道不孤——卢禹舜中国画作品展在重庆美术馆隆重开幕
2024年4月12日,由中国国家画院、重庆市文化和旅游发展委员会主办,重庆美术馆(重庆画院、重庆国画院)、北京八荒锦绣美术馆、中国国际文化交流基金会卢禹舜艺术基金承办的“天地人和•大道不孤——卢禹舜中国画作品展”开幕式在重庆…...
python-pytorch使用日志0.5.007
python-pytorch使用日志 1. optimizer.zero_grad()和model.zero_grad()的区别2. cbow和skip-gram的训练数据格式3. 获取cbow和skip-gram训练后的中文词向量4. 获取到词向量后可以做什么5. 余弦相似度结果的解释 1. optimizer.zero_grad()和model.zero_grad()的区别 都是清空模…...

itop4412编译内核时garbage following instruction -- `dmb ish‘ 解决方案
王德法 没人指导的学习路上磕磕绊绊太耗费时间了 今天编译4412开发板源码时报 garbage following instruction – dmb ish’ 以下是解决方案: 1.更新编译器 sudo apt-get install gcc-arm-linux-gnueabi 更新后修改Makefile 中编译器路径如下图 2.你以为更新完就可…...

(学习日记)2024.04.16:UCOSIII第四十四节:内存管理
写在前面: 由于时间的不足与学习的碎片化,写博客变得有些奢侈。 但是对于记录学习(忘了以后能快速复习)的渴望一天天变得强烈。 既然如此 不如以天为单位,以时间为顺序,仅仅将博客当做一个知识学习的目录&a…...

微信小程序Skyline模式下瀑布长列表优化成虚拟列表,解决内存问题
微信小程序长列表,渲染的越多就会导致内存吃的越多。特别是长列表的图片组件和广告组件。 为了解决内存问题,所以看了很多人的资料,都不太符合通用的解决方式,很多需要固定子组件高度,但是瀑布流是无法固定的…...
大语言模型LLM《提示词工程指南》学习笔记03
文章目录 大语言模型LLM《提示词工程指南》学习笔记03链式提示思维树检索增强生成自动推理并使用工具自动提示工程师Active-Prompt方向性刺激提示Program-Aided Language ModelsReAct框架Reflexion多模态思维链提示方法基于图的提示大语言模型LLM《提示词工程指南》学习笔记03 …...
239. 奇偶游戏(带权值并查集,邻域并查集,《算法竞赛进阶指南》)
239. 奇偶游戏 - AcWing题库 小 A 和小 B 在玩一个游戏。 首先,小 A 写了一个由 0 和 1 组成的序列 S,长度为 N。 然后,小 B 向小 A 提出了 M 个问题。 在每个问题中,小 B 指定两个数 l 和 r,小 A 回答 S[l∼r] 中…...

程序员做副业,AI头条,新赛道
大家好,我是老秦,6年编程,自由职业3年,今天继续更新副业内容。 在当今信息爆炸的时代,副业赚钱已成为许多人增加收入的重要途径。其中,AI头条模式以其独特的优势,吸引了越来越多的写作者加入。…...
Redis: 内存回收
文章目录 一、过期键删除策略1、惰性删除2、定时删除3、定期删除4、Redis的过期键删除策略 二、内存淘汰策略1、设置过期键的内存淘汰策略2、全库键的内存淘汰策略 一、过期键删除策略 1、惰性删除 顾名思义并不是在TTL到期后就立即删除,而是在访问一个key的时候&…...

【刷题篇】回溯算法(三)
文章目录 1、全排列2、子集3、找出所有子集的异或总和再求和4、全排列 II5、电话号码的字母组合6、括号生成 1、全排列 给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 class Solution { public:vector<vector<i…...
pe格式从入门到图形化显示(八)-导入表
文章目录 前言一、什么是Windows PE格式中的导入表?二、解析导入表并显示1.导入表的结构2.解析导入表3.显示导入表 前言 通过分析和解析Windows PE格式,并使用qt进行图形化显示 一、什么是Windows PE格式中的导入表? 在Windows中࿰…...
如何将Paddle(Lite)模型转换为TensorFlow(Lite)模型
模型间的相互转换在深度学习应用中很常见,paddlelite和TensorFlowLite是移动端常用的推理框架,有时候需要将模型在两者之间做转换,本文将对转换方法做说明。 环境准备 建议使用TensorFlow2.14,PaddlePaddle 2.6 docker pull te…...

最新Zibll子比主题V7.1版本源码 全新推出开心版
源码下载地址:Zibll子比主题V7.1.zip...

响应式布局(其次)
响应式布局 一.响应式开发二.bootstrap前端开发框架1.原理2.优点3.版本问题4.使用(1)创建文件夹结构(2)创建html骨架结构(3)引入相关样式(4)书写内容 5.布局容器(已经划分…...
arhtas idea plugin 使用手册
arthas idea plugin 使用文档 语雀...

数组算法——查询位置
需求 思路 使用二分查找找到第一个值,以第一个值作为界限,分为左右两个区间在左右两个区间分别使用二分查找找左边的7,:找到中间位置的7之后,将中间位置的7作为结束位置,依次循环查找,知道start>end,返回…...
【解决leecode打不开的问题】使用chrome浏览器和其他浏览器均打不开leecode
问题描述: 能进入leetcode力扣官网但是对某些栏目加载不出来,比如学习栏目能完成加载、题库栏目不能加载。 解决方法一:cookies缓存问题 首先尝试删除浏览器cookie缓存。 因为以下原因: Cookies损坏或过期:有些网站…...

尝试在手机上运行google 最新开源的gpt模型 gemma
Gemma介绍 Gemma简介 Gemma是谷歌于2024年2月21日发布的一系列轻量级、最先进的开放语言模型,使用了与创建Gemini模型相同的研究和技术。由Google DeepMind和Google其他团队共同开发。 Gemma提供两种尺寸的模型权重:2B和7B。每种尺寸都带有经过预训练&a…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...

visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...
关于 WASM:1. WASM 基础原理
一、WASM 简介 1.1 WebAssembly 是什么? WebAssembly(WASM) 是一种能在现代浏览器中高效运行的二进制指令格式,它不是传统的编程语言,而是一种 低级字节码格式,可由高级语言(如 C、C、Rust&am…...

SpringCloudGateway 自定义局部过滤器
场景: 将所有请求转化为同一路径请求(方便穿网配置)在请求头内标识原来路径,然后在将请求分发给不同服务 AllToOneGatewayFilterFactory import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; impor…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...