数据结构——双向链表dlist
前言:大家好😍,本文主要介绍了数据结构——双向链表dlist
一 双向链表定义
1. 双向链表的节点结构
二 双向链表操作
2.1 定义
2.2 初始化
2.3 插入
2.3.1 头插
2.3.2 尾插
2.3.3 按位置插
2.4 删除
2.4.1 头删
2.4.2 尾删
2.4.3 按位置删
2.5 其余操作
2.6 主函数测试
一 双向链表定义
双向链表(Doubly Linked List)是一种常见的线性数据结构,与单链表不同,双向链表的每个节点包含两个指针:一个指向前一个节点,一个指向后一个节点。这种结构使得双向链表支持从两个方向遍历,同时在插入和删除操作中更加灵活和高效。

1. 双向链表的节点结构
双向链表的每个节点包含三个部分:
-
数据域:存储数据元素。
-
前驱指针(
prev):指向当前节点的前一个节点。 -
后继指针(
next):指向当前节点的后一个节点。
二 双向链表操作
2.1 定义

//定义了双向链表的结构体
typedef int ELEM_TYPE;struct DNode
{ELEM_TYPE data; //数据域struct DNode* next; //下一个结点地址struct DNode* prior;//上一个
};typedef struct DNode DNode;
typedef struct DNode* PDNode;
2.2 初始化

void Init_Double_List(struct DNode* plist) //双向链表 第一种struct DNode*
{assert(plist != NULL);plist->next = NULL;plist->prior = NULL;
}
2.3 插入
2.3.1 头插


bool Insert_head(DNode* plist, ELEM_TYPE val)//二DNode*
{assert(plist != NULL);if (NULL == plist){exit(EXIT_FAILURE);}DNode* pnewnode = (DNode*)malloc(sizeof(DNode));if (NULL == pnewnode)exit(1);pnewnode->data = val;//插在辅助接点后面pnewnode->next = plist->next;pnewnode->prior = plist;if (!Is_Empty(plist)){pnewnode->next->prior = pnewnode;//这个也可以plist->next->prior = pnewnode;}plist->next = pnewnode;return true;}
2.3.2 尾插

bool Insert_tail(PDNode plist, ELEM_TYPE val)//三PDNode
{assert(NULL !=plist );if (NULL == plist){exit(EXIT_FAILURE);}//购买新节点DNode* pnewnode = (DNode*)malloc(sizeof(DNode));if (NULL == pnewnode)exit(1);pnewnode->data = val;//找到合适的待插入位置需要让一个临时指针p指向尾结点DNode* p = plist;while (p->next != NULL)p = p->next;//插入三行代码:只有三个指针域需要修改231 pnewnode->next = p->next;//nullpnewnode->prior = p;p->next = pnewnode;return true;}
2.3.3 按位置插


bool Insert_pos(DNode* plist, ELEM_TYPE val, int pos)
{assert(NULL != plist);if (NULL == plist){exit(EXIT_FAILURE);}//对pos合法性断言assert(pos >= 0 && pos <= Get_length(plist));//对pos判断 //pos=0 直接return头插函数//pos=length return尾插函数if (pos == 0){return Insert_head(plist, val);}else if(pos==Get_length(plist)){return Insert_tail(plist, val);}//剩下的pos都是合法且是中间位置,需要修改四个指针域//找到合适的插入位置让p指向待插入位置的上一个结点else{DNode* pnewnode = (DNode*)malloc(sizeof(DNode));if (NULL == pnewnode)exit(1);pnewnode->data = val;DNode* p = plist;while (p->next != NULL)p = p->next;//插入四行代码 因为有四个指针域要修改pnewnode->next = p->next;pnewnode->prior = p;pnewnode->next->prior = pnewnode;p->next = pnewnode;return true;}
}
2.4 删除
2.4.1 头删

bool Del_head(DNode* plist)
{//判空assert(NULL != plist);if (NULL == plist){exit(EXIT_FAILURE);}//判断链表是否为空if (Is_Empty(plist))return false;//申请俩个临时指针p和q,分别指向删除结点前驱和删除结点本身DNode* p = plist;//可以不要这行DNode* q = p->next;//区分情况 若是只有唯一一个有效结点 则只要需要修改一个指针域// >1则修改俩个指针域if (Get_length(plist)>1){q->next->prior = p;}//跨越指向+释放p->next = q->next;free(q);q = NULL;return true;}
2.4.2 尾删

bool Del_tail(DNode* plist)
{assert(NULL != plist);if (NULL == plist){exit(EXIT_FAILURE);}//对双向链表判空if (Is_Empty(plist))return false;//辅助接点后有结点就可以尾删 //申请俩个临时指针p和q,分别指向删除结点前驱和删除结点本身DNode* p = plist;while (p->next->next != NULL)p = p->next;DNode* q = p->next;//跨越指向+释放p->next = q->next;free(q);q = NULL;return true;
}
2.4.3 按位置删
2.5 其余操作
//9.判空
bool Is_Empty(DNode* plist)
{return plist->next == NULL;
}//10获取有效值长度
int Get_length(DNode* plist)
{int count = 0;DNode* p = plist->next;for (; p != NULL;p=p->next){count++;}return count;
}//11.清空
void Clear(DNode* plist)
{Destroy1(plist);
}//12.销毁1(需要辅助节点参与进来)
void Destroy1(DNode* plist)
{//无限头删while (plist->next != NULL){Del_head(plist);}
}//13.销毁2(不需要辅助节点参与进来)相当于单链表的销毁
void Destroy2(DNode* plist)
{//不借助头结点//要用俩个指针pq去搭配 销毁所有结点//0.assert head //1.申请指针p,让其指向第一个有效结点DNode* p =plist->next;//p有可能为NULL, 有可能不空//2.申请指针q,先不给q赋值DNode* q = NULL; //因为p有可能是NULL,所以不能现在直接把p->next给到q//3.反复通过p和q打配合,去销毁后续节点while (p != NULL){q = p->next;free(p);p = q;}//4.节点全部销毁完毕,别忘了把辅助节点的指针域置空plist->next = NULL;//这一行代码可以帮助,下一次启用的时候,辅助节点不用初始化了
}//14.打印
void Show(DNode* plist)
{DNode* p = plist->next;for (; p != NULL;p=p->next){printf("%d", p->data);}printf("\n");
}
2.6 主函数测试
相关文章:
数据结构——双向链表dlist
前言:大家好😍,本文主要介绍了数据结构——双向链表dlist 一 双向链表定义 1. 双向链表的节点结构 二 双向链表操作 2.1 定义 2.2 初始化 2.3 插入 2.3.1 头插 2.3.2 尾插 2.3.3 按位置插 2.4 删除 2.4.1 头删 2.4.2 尾删 2.4.3 按…...
IDEA 一键完成:打包 + 推送 + 部署docker镜像
1、本方案要解决场景? 想直接通过本地 IDEA 将最新的代码部署到远程服务器上。 2、本方案适用于什么样的项目? 项目是一个 Spring Boot 的 Java 项目。项目用 maven 进行管理。项目的运行基于 docker 容器(即项目将被打成 docker image&am…...
图像分类数据集
《动手学深度学习》-3.5-学习笔记 # 通过ToTensor实例将图像数据从PIL类型变换成32位浮点数格式, # 并除以255使得所有像素的数值均在0~1之间 trans transforms.ToTensor()#用于将图像数据从 PIL 图像格式(Python Imaging Libraryÿ…...
设计模式之美
UML建模 统一建模语言(UML)是用来设计软件的可视化建模语言。它的语言特点是简单 统一 图形化 能表达软件设计中的动态与静态信息。 UML的分类 动态结构图: 类图 对象图 组件图 部署图 动态行为图: 状态图 活动图 时序图 协作…...
2025-03-15 学习记录--C/C++-PTA 练习3-4 统计字符
合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 练习3-4 统计字符 本题要求编写程序,输入10个字符,统计其中英文字母、空格或回车、…...
802.11标准
系列文章目录 文章目录 系列文章目录一、相关知识二、使用步骤1.802.11修正比较2.802.11ac 三、杂记 一、相关知识 跳频扩频:射频信号可分为窄带信号和扩频信号。如果射频信号的带宽大于承载数据所需的带宽,该信号就属于扩频信号。跳频扩频(FHSS)是一种…...
母婴商城系统Springboot设计与实现
项目概述 《母婴商城系统Springboot》是一款基于Springboot框架开发的母婴类电商平台,旨在为母婴产品提供高效、便捷的在线购物体验。该系统功能全面,涵盖用户管理、商品分类、商品信息、商品资讯等核心模块,适合母婴电商企业或个人开发者快…...
C#通过API接口返回流式响应内容---分块编码方式
1、背景 上一篇文章《C#通过API接口返回流式响应内容—SSE方式》阐述了通过SSE(Server Send Event)方式,由服务器端推送数据到浏览器。本篇是通过分块编码的方式实现 2、效果 3、具体代码 3.1 API端实现 [HttpGet] public async Task Chu…...
游戏引擎学习第158天
回顾和今天的计划 我们在这里会实时编码一个完整的游戏,没有使用引擎或库,一切都由我们自己做所有的编程工作,游戏中的每一部分,无论需要做什么,我们都亲自实现,并展示如何完成这些任务。今天,…...
如何在电脑上使用 Jupyter Notebook 通过 SSH 远程连接树莓派Zero
有无数种方式通过SSH远程连接树莓派,但对于树莓派Zero 2W这种硬件资源有限的板子,因为内存有限Pycharm干脆不能通过SSH连接树莓派Zero 2W。VScode通过SSH连接时,也会因为资源有限时常断线。因此,我们就要用轻量级的编辑器Jupyter …...
[新能源]新能源汽车快充与慢充说明
接口示意图 慢充接口为交流充电口(七孔),快充接口为直流充电口(九孔)。 引脚说明 上图给的是充电口的引脚图,充电枪的为镜像的。 慢充接口引脚说明 快充接口引脚说明 充电流程 慢充示意图 慢充&…...
《解锁华为黑科技:MindSpore+鸿蒙深度集成奥秘》
在数字化浪潮汹涌澎湃的当下,人工智能与操作系统的融合已成为推动科技发展的核心驱动力。华为作为科技领域的先锋,其AI开发框架MindSpore与鸿蒙系统的深度集成备受瞩目,开启了智能生态的新篇章。 华为MindSpore:AI框架的创新先锋…...
HCIA-ACL
一、基本概念 1、概念:ACL即访问控制列表,是一种基于包过滤的访问控制技术。由一条或多条规则组成的集合,通过定义动作来确保哪些数据包可以通过,哪些需要被阻止。 2、基本原理:ACL 通过规则对数据包分类,…...
深入解析 React 最新特性:革新、应用与最佳实践
深入解析 React 最新特性:革新、应用与最佳实践 1. 引言 React 作为前端开发的核心技术之一,近年来不断推出 新的 API 和优化机制,从 Concurrent Rendering(并发模式) 到 Server Components(服务器组件&a…...
通信协议传输过程中的序列化和反序列化机制
在通信协议的传输过程中,序列化和反序列化是核心机制之一。它们影响数据的传输效率、兼容性和解析速度,特别是在分布式系统、RPC(远程过程调用)、消息队列和微服务架构中至关重要。 1. 什么是序列化和反序列化? 序列化…...
在IDEA中连接达梦数据库:详细配置指南
达梦数据库(DM Database)作为国产关系型数据库的代表,广泛应用于企业级系统开发。本文将详细介绍如何在IntelliJ IDEA中配置并连接达梦数据库,助力开发者高效完成数据库开发工作。 准备工作 1. 下载达梦JDBC驱动 访问达梦官方资…...
OkHttp 的证书设置
在 Android 开发中,通过 OkHttp 自定义 SSLSocketFactory 和 X509TrustManager 可以有效增强 HTTPS 通信的安全性,防止中间人攻击(如抓包工具 Charles/Fiddler 的拦截)。以下是实现防抓包的关键技术方案: 一、Okhttp设…...
机器视觉工程师如何学习C#通讯
建议大家可以提前测试,真实模拟现场的情况,或者采用虚拟串口,虚拟网口频繁测试通讯的稳定性,以后有现场需要,可以快速布局到现场。 机器视觉工程师学习C#通讯协议需要结合工业场景需求,掌握基础协议原理、常…...
数字电子技术会被淘汰吗?模拟电子技术的未来发展与应用
引言 当今世界正处在数字电子技术飞速发展的时代。自上世纪中叶以来,集成电路中的晶体管数量按照摩尔定律呈指数级增长,计算设备性能大幅提升。一个典型例子是,我们口袋中的智能手机拥有的运算能力远超早期计算机:iPhone 14的处理…...
基于yolov8+streamlit实现目标检测系统带漂亮登录界面
【项目介绍】 基于YOLOv8和Streamlit实现的目标检测系统,结合了YOLOv8先进的目标检测能力与Streamlit快速构建交互式Web应用的优势,为用户提供了一个功能强大且操作简便的目标检测平台。该系统不仅具备高精度的目标检测功能,还拥有一个漂亮且…...
软件性能测试与功能测试联系和区别
随着软件开发技术的迅猛发展,软件性能测试和功能测试成为了确保软件质量的两个重要环节。那么只有一字之差的性能测试和功能测试分别是什么?又有哪些联系和区别呢? 一、软件性能测试是什么? 软件性能测试是为了评估软件系统在特定条件下的表现,包…...
交易系统【三】网关
第二章本来是要讲消息总线,审核说是过度宣传,就放弃了,不纠结,先跳过。 网关和消息总线的底层技术都和网络相关,两者也有很重要的差别。消息总线主要用于内网,受交换机和网卡影响比较大,网络状…...
Axure设计之堆叠柱状图教程(中继器)
堆叠柱状图是一种常用的数据可视化工具,它通过在同一柱状图内堆叠不同类别的数据,以展示每个类别在总体中的贡献或占比。堆叠柱状图不仅可以帮助我们观察数据的总量,还能清晰地揭示各部分之间的关系和变化趋势。以下是一个使用Axure制作动态效…...
antd的Form表单校验的方式有几种
Ant Design 的 Form 组件提供了多种灵活的表单校验方式,以下是常见的几种方法及示例: 1. 内置校验规则 通过 rules 配置预定义的校验规则(如必填、长度、格式等)。 <Form.Itemname"email"label"邮箱"rul…...
前端面试:React hooks 调用是可以写在 if 语句里面吗?
在 React 中,Hooks 是一种新的特性,允许你在函数组件中使用状态(state)和其他 React 特性。非常重要的一点是,React Hooks 必须遵循特定的规则,以确保组件的行为一致。 React Hooks 使用规则 只能在函数组…...
本地部署Hive集群
规划 服务机器Hive本体部署在Node1元数据服务所需的关系型数据库(MYSQL)部署在Node1 安装MYSQL数据库 # 更新密钥 rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022# 安装Mysql yum库 rpm -Uvh http://repo.mysql.com//mysql57-community-release-el7-7.noarch.…...
CNN的激活函数
我们来对比 Sigmoid、Softmax 和 ReLU 这三种激活函数的相同点和不同点,并分别说明它们相较于其他两种激活函数的优点。 相同点 都是非线性激活函数: 这三种激活函数都能为神经网络引入非线性特性,使网络能够学习复杂的模式。 广泛应用于深度…...
【愚公系列】《高效使用DeepSeek》001-什么是DeepSeek
标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主,腾讯云内容共创官,掘金优秀博主,亚马逊技领云博主,51CTO博客专家等。近期荣誉2022年度…...
零成本本地化搭建开源AI神器LocalAI支持CPU推理运行部署方案
文章目录 前言1. Docker部署2. 简单使用演示3. 安装cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 嘿,小伙伴们!今天给大家带来一个超酷的黑科技——LocalAI。没错,你没听错,就是那个能在你的个人电脑上运行大型语言模…...
Visual Studio Code 基本使用指南
Visual Studio Code(简称 VSCode)是一款由微软开发的免费、开源、跨平台的代码编辑器,凭借其轻量级设计、丰富的插件生态和强大的功能,成为全球开发者的首选工具。本文将从安装配置到核心功能,全面解析 VSCode 的基本使…...
