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

【数据结构】双向链表

目录

数据结构之双向链表::

                                        List.h

                                        List.c

                                        1.创建返回链表的头结点

                                        2.双向链表初始化

                                        3.双向链表打印

                                        4.双向链表销毁

                                        5.双向链表尾插

                                        6.双向链表尾删

                                        7.双向链表头插

                                        8.双向链表头删

                                        9.双向链表查找

                                      10.双向链表在pos前插入

                                      11.双向链表删除pos位置

                                      12.双向链表判空

                                      13.双向链表长度

                                      14.顺序表与链表的区别


数据结构之双向链表::

List.h

#pragma once
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>
typedef int LTDataType;
typedef struct ListNode
{struct ListNode* next;struct ListNode* prev;LTDataType data;
}LTNode;
LTNode* ListInit();
void ListPrint(LTNode* phead);
void ListPushBack(LTNode* phead, LTDataType x);
void ListPushFront(LTNode* phead, LTDataType x);
void ListPopBack(LTNode* phead);
void ListPopFront(LTNode* phead);
bool ListEmpty(LTNode* phead);
size_t ListSize(LTNode* phead);
LTNode* ListFind(LTNode* phead, LTDataType x);
//在pos之前插入
void ListInsert(LTNode* pos, LTDataType x);
//删除pos位置
void ListErase(LTNode* pos);
void ListDestory(LTNode* phead);

List.c

1.创建返回链表的头结点

LTNode* BuyListNode(LTDataType x)
{LTNode* node = (LTNode*)malloc(sizeof(LTNode));if (node == NULL){perror("malloc fail");exit(-1);}node->next = NULL;node->prev = NULL;
}

2.双向链表初始化

LTNode* ListInit()
{LTNode* guard = (LTNode*)malloc(sizeof(LTNode));if (guard == NULL){perror("malloc fail");exit(-1);}guard->next = guard;guard->prev = guard;return guard;
}

3.双向链表打印

void ListPrint(LTNode* phead)
{assert(phead);printf("guard<=>");LTNode* cur = phead->next;while (cur != phead){printf("%d<=>", cur->data);cur = cur->next;}printf("\n");
}

4.双向链表销毁

//可以传二级 内部置空头结点
//建议:也可以考虑使用一级指针 让调用ListDestory的人将其置空 保持接口的一致性
void ListDestory(LTNode* phead)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){LTNode* next = cur->next;free(cur);cur = next;}free(phead);//phead = NULL;
}

5.双向链表尾插

void ListPushBack(LTNode* phead, LTDataType x)
{assert(phead);LTNode* newnode = BuyListNode(x);LTNode* tail = phead->prev;tail->next = newnode;newnode->prev = tail;newnode->next = phead;phead->prev = newnode;
}

6.双向链表尾删

void ListPopBack(LTNode* phead)
{assert(phead);//链表为空返回true 取反为假就报错assert(!ListEmpty(phead));//删掉最后一个结点 哨兵位变成自己指向自己 代码依然成立LTNode* tail = phead->prev;LTNode* prev = tail->prev;prev->next = phead;phead->prev = prev;free(tail);tail = NULL;
}

7.双向链表头插

void ListPushFront(LTNode* phead, LTDataType x)
{assert(phead);//先链接newnode和phead->next结点之间的关系/*LTNode* newnode = BuyListNode(x);newnode->next = phead->next;phead->next->prev = newnode;phead->next = newnode;newnode->prev = phead;*///不关心先后顺序LTNode* newnode = BuyListNode(x);LTNode* first = phead->next;phead->next = newnode;newnode->prev = phead;newnode->next = first;first->prev = newnode;
}

8.双向链表头删

void ListPopFront(LTNode* phead)
{assert(phead);//链表为空返回true 取反为假就报错assert(!ListEmpty(phead));//删到剩最后一个结点时 first指向最后一个结点 second指向哨兵位结点 删到最后哨兵位自己指向自己 代码依然成立LTNode* first = phead->next;LTNode* second = first->next;phead->next = second;second->prev = phead;free(first);first = NULL;
}

9.双向链表查找

//双向链表的查找可以替代其修改函数
LTNode* ListFind(LTNode* phead, LTDataType x)
{assert(phead);LTNode* cur = phead->next;while (cur != phead){if (cur->data == x){return cur;}cur = cur->next;}return NULL;
}

10.双向链表在pos前插入

//在pos之前插入
void ListInsert(LTNode* pos, LTDataType x)
{assert(pos);LTNode* prev = pos->prev;LTNode* newnode = BuyListNode(x);//prev newnode posprev->next = newnode;newnode->prev = prev;newnode->next = pos;pos->prev = newnode;
}
//ListInsert(phead,x)代替尾插
//ListInsert(phead->next,x)代替头插

11.双向链表删除pos位置

//删除pos位置
void ListErase(LTNode* pos)
{assert(pos);LTNode* prev = pos->prev;LTNode* next = pos->next;prev->next = next;next->prev = prev;free(pos);//pos = NULL;置空并不起作用
}
//ListErase(phead->prev)代替尾删
//ListErase(phead->next)代替头删

12.双向链表判空

bool ListEmpty(LTNode* phead)
{assert(phead);return phead->next == phead;
}

13.双向链表长度

size_t ListSize(LTNode* phead)
{assert(phead);size_t n = 0;LTNode* cur = phead->next;while (cur != phead){++n;cur = cur->next;}return n;
}

14.顺序表与链表的区别

不同点顺序表链表
存储空间上物理上一定连续逻辑上连续但是物理上不一定连续
随机访问支持O(1)不支持O(N)
任意位置插入或者删除元素可能需要搬移元素,效率低O(N)只需修改指针指向
插入动态顺序表,空间不够时需要扩容没有容量的概念
应用场景元素高效存储+频繁访问任意位置插入和删除频繁
缓存利用率

备注:缓存利用率参考存储体系结构以及局部原理性

顺序表的优点:
1.尾插尾删的效率很高
2.可以用下标随机访问
3.相比链表结构 CPU高速缓存命中率更高
顺序表的缺点:
1.头部和中部插入效率低——O(N)
2.扩容时的性能消耗+扩容时的空间浪费
链表的优点:
1.任意位置插入删除效率很高——O(1)
2.按需申请释放
链表的缺点:
1.不支持随机访问
注:三级缓存被称为CPU周围的禁卫军
CPU执行指令不会直接访问内存 
1.先看数据在不在三级缓存,在(命中),直接访问
2.不在(不命中),先加载到缓存,再访问
注:加载到缓存时,会将需要加载的位置开始的一段都加载进缓存,(加载多少取决于硬件)
由于顺序表的数据彼此之间的地址紧密联系 所以加载到高速缓存时命中率高 但链表不然 更可能会导致缓存污染 

 

相关文章:

【数据结构】双向链表

目录 数据结构之双向链表&#xff1a;&#xff1a; List.h List.c 1.创建返回链表的头结点 2.双向链表初始化 3.双向链表打印 4.双向链表销毁 5.双向链表尾插 6.双向链表尾删 7.双向链表头插 8.双向链表头删 9.双向链表查找 10.双向链表在pos前插入 11.双向链表删除pos位置 12…...

Editor工具开发基础三:自定义组件菜单拓展 CustomEditor

一.创建脚本路径 创建脚本路径不再限制 一般写在自定义组件类的下边二.特性CustomEditor 定义主设计图面由自定义代码实现数组的编辑器。两个构造函数1.public CustomEditor(Type inspectedType);2.public CustomEditor(Type inspectedType, bool editorForChildClasses);参数意…...

拒绝摆烂!神仙网站Python自学,一路从入门闯到最后,边学边玩

前言给大家推荐3个边玩边学python的网站在刚接触编程&#xff0c;培养对其持续的兴趣是最最重要的事情辣&#xff01;&#xff01;&#xff01;因为前期需要大量的基础代码知识积累&#xff0c;这个过程对于不少人来说还是挺枯燥的&#xff0c;很有可能学到一半就放弃了&#x…...

Linux基础命令-locate快速查找文件

文章​​​​​​​目录 locate 命令介绍 语法格式 基本参数 参考实例 1&#xff09;查找1.txt相关的文件 2&#xff09;查找包含pass和txt都有的文件 3&#xff09;只匹配文件名&#xff0c;有路径的情况下不进行匹配 4&#xff09;匹配不区分大小写的文件 5&#…...

揭穿数据分析的六大谎言

目前许多企业在决策时仍沿用以往的个人经验&#xff0c;没有用数据说话&#xff0c;这在实际决策运行时会出现很多问题。在数据分析行业发展成熟的国家&#xff0c;90%的市场决策和经营决策都是通过数据分析研究确定的。用数据说话&#xff0c;重视定量分析&#xff0c;也逐渐成…...

LinkSLA智能运维技术派-Redis的监控

Redis是一个开源&#xff0c;内存存储的数据服务器&#xff0c;可用作数据库、高速缓存和消息队列代理等场景。 首先我们对内存进行监控&#xff0c;主要指标如下&#xff1a; - used_memory:使用内存 - used_memory_rss:从操作系统分配的内存 - mem_fragmentation_ratio:内…...

Hugging face 模型微调学习:T5-base的微调

最近想做一点文本生成的小实验&#xff0c;无意发现了NLPer应该了解到了一个网站&#xff1a;Hugging face。 Hugging face 在 github上开源了一个Transformers库&#xff0c;允许用户上传和下载的预训练的模型&#xff0c;并进行原有模型的基础上进行微调。如此&#xff0c;使…...

JavaScript 测试 Prototype

文章目录JavaScript 测试 Prototype引用 PrototypePrototype 描述测试 PrototypeJavaScript 测试 Prototype 测试 JavaScript 框架库 - Prototype 引用 Prototype 如需测试 JavaScript 库&#xff0c;您需要在网页中引用它。 为了引用某个库&#xff0c;请使用 <!DOCTYP…...

pnpm / yarn / npm管理依赖包

pnpm pnpm官网&#xff1a;https://pnpm.io/zh/ pnpm安装方式有很多&#xff0c;详见官网。 用最简单的npm来安装pnpm&#xff1a;npm install -g pnpm pnpm安装依赖包 pnpm install # 安装所有项目中的依赖包 pnpm install vue # 安装依赖到dependencies pnpm in…...

注意力机制详解系列(一):注意力机制概述

&#x1f468;‍&#x1f4bb;作者简介&#xff1a; 大数据专业硕士在读&#xff0c;CSDN人工智能领域博客专家&#xff0c;阿里云专家博主&#xff0c;专注大数据与人工智能知识分享。 &#x1f389;专栏推荐&#xff1a; 目前在写CV方向专栏&#xff0c;更新不限于目标检测、…...

搜索引擎 Elasticsearch 的三大坑

搜索引擎的坑 ES 搜索引擎系列文章汇总&#xff1a; 一、别只会搜日志了&#xff0c;求你懂点原理吧 二、ES 终于可以搜到”悟空哥“了&#xff01; 三、1W字&#xff5c;40 图&#xff5c;硬核 ES 实战 本文主要内容如下&#xff1a; 搜索引擎现在是用得越来越多了&#…...

运营级手机直播平台源码 短视频直播带货APP源码

短视频直播带货APP源码 全开源原生直播APP源码 前端&#xff1a;原生APP 安卓端&#xff1a;Java 苹果端&#xff1a;OC 后台&#xff1a;PHP 数据库&#xff1a;Mysql 技术框架&#xff1a;Thinkphp5.1 系统特色功能包括&#xff1a;礼物系统&#xff1b;提现方式&#…...

http/HTTPS相关的一些知识

2、http和https HTTP&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。HTTP 是应用层协议&#xff0c;它以 TCP&#xff08;传输层&#xff09;作为底层协议&#xff0c;默认端口为 80。 http的通信过程&#xff1a;服务器在80端口等待客户的请…...

MySQL高可用 集群(MHA)

1. MHA集群概述 集群的定义&#xff1a;多台服务器一起提供相同的服务&#xff0c;如&#xff08;web集群&#xff09;等。常见集群的分类&#xff1a; LB&#xff08;负载均衡集群&#xff09;&#xff1a;服务器共同平均分摊处理客户端的多次连接请求。 HA&#xff08;高可用…...

【JavaScript速成之路】JavaScript运算符

&#x1f4c3;个人主页&#xff1a;「小杨」的csdn博客 &#x1f525;系列专栏&#xff1a;【JavaScript速成之路】 &#x1f433;希望大家多多支持&#x1f970;一起进步呀&#xff01; 文章目录前言运算符1&#xff0c;算术运算符2&#xff0c;递增递减运算符3&#xff0c;比…...

计网个人作业05

R1 链路层可以提供如下服务 链路层服务IP能否提供&#xff1f;TCP能否提供&#xff1f;流量控制✔差错检测✔✔差错纠正全双工、半双工✔ R2 不冗余 IP层有丢包的情况⼀个⻓的 TCP 报⽂段会被分⽚成多个 IP 数据报形成不同的帧&#xff0c;不同的帧可能会被不同链路传输。同…...

码匠 × OpenAI :快速生成 SQL 语句,提升开发效率!

目录 使用 OpenAI 生成 SQL 码匠连接与集成 OpenAI 总结 关于码匠 在码匠中&#xff0c;编写 SQL 语句&#xff0c;并结合码匠一系列开箱即用的组件实现复杂的业务逻辑&#xff0c;是很常见的应用开发场景。然而&#xff0c;不同的数据库在 SQL 增删改查操作语法、类型字段和…...

电脑显示屏不亮但是主机已开机?5种原因以及解决方案

电脑与我们的日常生活和工作密切相关&#xff0c;缺了它我们工作就很难正常展开。电脑使用久了&#xff0c;难免出现一些小问题&#xff0c;比如&#xff1a;电脑显示屏不亮但是主机已开机&#xff0c;这是什么原因造成的&#xff1f;我们应该怎么处理&#xff1f; 可能很多人…...

公司项目vue cli2升级到vue cli3

背景&#xff1a;公司项目历时时间较长&#xff0c;通过长时间的迭代&#xff0c;目前项目文件较多&#xff08;src目录下有2217个文件&#xff09;&#xff0c;系统庞大&#xff0c; 之前通过vue cli2脚手架构建的项目框架&#xff0c;在本地开发时已经明显感觉到吃力&#xf…...

流程图培训

工具 wps 目前咱们在新建里面&#xff0c;可以新建流程图 构成流程图的图形符号及其作用 常用的流程图介绍 flowchart 和 BPMN 两种 flowchart: 最开始的全名是”Process Flow Charts”&#xff0c;即处理流程图表。 BPMN&#xff1a; 定义了业务流程图&#xff0c;其基…...

工业AI落地:从数据冷启动到高质数据工程实战

1. 为什么“数据为中心”不是口号&#xff0c;而是工程现场的真实压力去年冬天&#xff0c;我帮一家做工业缺陷检测的初创公司做模型交付。他们拿来的数据集只有237张标注图&#xff0c;全是产线停机时人工拍的——光照不均、角度单一、连螺丝孔都只拍正面。当时团队信心满满&a…...

FairyGUI GLoader动效动态接管与运行时替换实战

1. 这不是简单的“换图”&#xff0c;而是动效资源的动态接管机制在 FairyGUI for Unity 项目里&#xff0c;当你看到GLoader组件上挂着一个.png或.jpg&#xff0c;心里默认它就是张静态图——但一旦你给它赋值一个MovieClip、GAnimation&#xff0c;甚至是一段从 AssetBundle …...

揭秘当下匹克球鞋销售厂家,背后隐藏着怎样的行业秘密?

在运动市场中&#xff0c;匹克球运动正逐渐兴起&#xff0c;匹克球鞋销售厂家也受到了更多关注。下面&#xff0c;让我们深入探究其中的行业秘密。市场现状与痛点行业报告显示&#xff0c;随着匹克球运动的普及&#xff0c;匹克球鞋市场规模不断扩大&#xff0c;但也存在诸多痛…...

基因鉴定步骤及常见问题

一、基因组 DNA 提取&#xff08;一&#xff09;消化鼠尾消化液配方为溶剂水与SDS、酶。Solution&#xff1a;0.5%SDS破坏细胞膜和核膜&#xff0c;释放DNA。Enzyme&#xff1a;1 mg/ml蛋白酶K分解样本中的蛋白质&#xff0c;释放DNA。&#xff08;二&#xff09;样品处理1、小…...

智慧农业棉花棉铃病害成熟度检测数据集VOC+YOLO格式969张6类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数)&#xff1a;969标注数量(xml文件个数)&#xff1a;969标注数量(txt文件个数)&#xff1a;969标注类别数&…...

AI知识擦除:Gemini3.1Pro能否真正遗忘危险?

概念擦除&#xff1a;能否从 Gemini 3.1 Pro 中删除特定危险知识&#xff1f;——理性看待“遗忘”与“可控”在 2026 年的 AI 热点语境下&#xff0c;“可控”和“可验证”成为讨论主线。除了提升模型能力&#xff0c;人们也更关心另一件事&#xff1a;**当模型掌握了不希望被…...

抖音内容下载终极指南:5分钟搞定批量下载与去水印

抖音内容下载终极指南&#xff1a;5分钟搞定批量下载与去水印 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback support. …...

从0到千万级调用量:物流调度Agent性能压测极限突破路径(QPS 2400→8900全过程监控数据集首次披露)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;从0到千万级调用量&#xff1a;物流调度Agent性能压测极限突破路径&#xff08;QPS 2400→8900全过程监控数据集首次披露&#xff09; 面对日均超1200万单的跨城干线同城即时配送混合调度请求&#xff…...

AI模型连接失败的四大根源与10分钟排查指南

1. 这不是网络问题&#xff0c;是连接逻辑没对上“模型连接失败”这六个字&#xff0c;几乎每个刚接触AI开发的新手都见过——在本地跑通了代码&#xff0c;调用OpenAI或国内大模型API时突然卡在requests.exceptions.ConnectionError&#xff0c;或者返回一串看不懂的401 Unaut…...

Rshell框架实战:红队内网渗透的信道管理与双平台协同

1. 这不是“教你怎么黑”&#xff0c;而是还原一次真实红队作业的完整切片Rshell框架——这个名字在渗透测试圈子里不算陌生&#xff0c;但真正把它用透、用稳、用出生产级效果的人&#xff0c;远比想象中少。我见过太多人把Rshell当成一个“带图形界面的msfvenomnc组合包”&am…...