数据结构 - C/C++ - 链表
目录
结构特性
内存布局
结构样式
结构拓展
单链表
结构定义
节点关联
插入节点
删除节点
常见操作
双链表
环链表
结构容器
结构设计
结构特性
-
线性结构的存储方式
-
顺序存储 - 数组
-
链式存储 - 链表
-
-
线性结构的链式存储是通过任意的存储单元来存储线性表当中的数据元素。
-
存储单元可以是连续的也可以是不连续的。
-
线性结构的顺序存储中每个元素只需要存储其元素数据即可。
-
线性结构的链式存储除了存储元素数据外,还有存储后继元素的内存地址。
-
-
结构概念
-
节点(Node) - 链式存储结构中的元素单位为节点,通常由数据域和指针域共同组成。
-
数据域(Data) - 存储节点值。
-
指针域(Next) - 存储节点指向的下一个节点的内存地址。
-
头节点(Head) - 链表头部节点。
-
尾节点(Tail) - 链表的结束位置节点,其指针域指向NULL,表示了链表结束。
-
内存布局
-
链式存储
-
-
节点样式
-
结构样式
-
单链表
-
每个节点只有一个指针域,指向下一个节点。
-
-
-
双向链表
-
每个节点存在两个指针域,一个指向前节点,一个指向后节点。
-
-
-
循环链表
-
链表尾部节点指向头节点。
-
-
结构拓展
单链表
结构定义
typedef struct ListNode
{//数据域int value;//指针域ListNode* Next;//赋值域ListNode(int num) : value(num), Next(nullptr){}
};
节点关联
ListNode* Node1 = new ListNode(1);ListNode* Node2 = new ListNode(2);ListNode* Node3 = new ListNode(3);ListNode* Node4 = new ListNode(4);ListNode* Node5 = new ListNode(5);Node1->Next = Node2;Node2->Next = Node3;Node3->Next = Node4;Node4->Next = Node5;Node5->Next = NULL;
插入节点
void Insert(ListNode* Cur, ListNode* Node)
{ListNode* Temp = Cur->Next;Cur->Next = Node;Node->Next = Temp;
}
删除节点
void Remove(ListNode* Cur)
{//当前节点.Next = 当前节点.下一个节点.下一个节点ListNode* Node6 = Cur->Next;ListNode* Node3 = Node6->Next;Cur->Next = Node3;delete Node6;
}
常见操作
//遍历节点int nIndex = 0;ListNode* pTemp = Node1;while (pTemp != NULL){printf("Index -> [%d] -> Data -> [%d] \r\n", nIndex, pTemp->value);++nIndex;pTemp = pTemp->Next;}
双链表
#include <iostream>class ListNode
{
public://数据域int value;//指针域ListNode* Prev;ListNode* Next;//赋值域ListNode(int Num): value(Num), Prev(nullptr), Next(nullptr) {}
};//追加节点
void Append(ListNode* Head , int val)
{ListNode* newNode = new ListNode(val);ListNode* tempNode = Head;while (tempNode->Next != NULL){tempNode = tempNode->Next;}tempNode->Next = newNode;newNode->Prev = tempNode;newNode->Next = NULL;}//添加节点
void Insert(ListNode* Head, int val)
{ListNode* newNode = new ListNode(val);ListNode* HeadNext = Head->Next;Head->Next = newNode;newNode->Prev = Head;newNode->Next = HeadNext;HeadNext->Prev = newNode;/*Node2.Next = NodeCC;NodeCC.Prev = Node2;NodeCC.Next = Node3;Node3.Prev = NodeCC;*/}//移除节点
void Remove(ListNode* Head)
{ListNode* tempNode = Head;while (tempNode->Next != NULL){tempNode = tempNode->Next;}tempNode->Prev->Next = NULL;delete tempNode;
}//删除节点
void Erase(ListNode* Head)
{//当前节点.上一个.下一个 = 当前节点.下一个//当前节点.下一个.上一个 = 当前节点.上一个Head->Prev->Next = Head->Next;Head->Next->Prev = Head->Prev;
}int main()
{ListNode* Node1 = new ListNode(1);ListNode* Node2 = new ListNode(2);ListNode* Node3 = new ListNode(3);ListNode* Node4 = new ListNode(4);ListNode* Node5 = new ListNode(5);Node1->Prev = NULL;Node1->Next = Node2;Node2->Prev = Node1;Node2->Next = Node3;Node3->Prev = Node2;Node3->Next = Node4;Node4->Prev = Node3;Node4->Next = Node5;Node5->Prev = Node4;Node5->Next = NULL;Append(Node1 ,0xCC);Insert(Node2 ,0xDD);Remove(Node1);Erase(Node3);return 0;
}
环链表
#include <iostream>class ListNode
{
public://数据域int value;//指针域ListNode* Next;//赋值域ListNode(int Num) : value(Num), Next(nullptr){}
};int main()
{ListNode* Node1 = new ListNode(1);ListNode* Node2 = new ListNode(2);ListNode* Node3 = new ListNode(3);ListNode* Node4 = new ListNode(4);ListNode* Node5 = new ListNode(5);Node1->Next = Node2;Node2->Next = Node3;Node3->Next = Node4;Node4->Next = Node5;Node5->Next = Node1;ListNode* tempNode = Node1;do{printf("%d \r\n", tempNode->value);tempNode = tempNode->Next;} while (tempNode != Node1);return 0;
}
结构容器
-
std:list
-
构造函数
-
默认构造函数
-
有参构造函数
-
拷贝构造函数
-
列表构造函数
-
默认析构函数
-
-
大小函数
-
节点数量
-
是否为空
-
清空数据
-
-
功能函数
-
插入元素
-
头部插入
-
尾部插入
-
指定插入
-
删除元素
-
修改元素
-
访问元素
-
结构设计
#include <iostream>class Node
{
public://数据域int value;//指针域Node* Prev;Node* Next;//赋值域Node(int Num, Node* p = nullptr, Node* n = nullptr) : value(Num), Prev(p), Next(n) {}
};class List
{
public://头部节点Node* Head;//尾部节点Node* Tail;//节点数量size_t size;public://默认构造List();//有参构造List(int Count, int value);//拷贝构造List(const List& ref);//列表构造List(std::initializer_list<int> initList);//默认析构~List();public://是否为空bool IsEmpty();//节点数量size_t GetSize();//清空容器void Clear();public://尾部插入void Push_Back(int value);//头部插入void Push_Front(int value);//指定插入void Insert(int InsertValue, int value);//尾部移除void Pop_Back();//头部移除void Pop_Front();//按值匹配void Remove(int value);//查找节点bool Find(int value);public://赋值运算符List& operator=(const List & other);//下标运算符int& operator[](int Index);};std::ostream& operator<<(std::ostream& output, const List& obj);List::List()
{this->Head = nullptr;this->Tail = nullptr;this->size = 0;
}List::List(int Count, int value) : Head(nullptr), Tail(nullptr), size(0)
{while (Count--){Push_Back(value);}
}List::List(const List& ref) : Head(nullptr), Tail(nullptr), size(0)
{Node* node = ref.Head;while (node){Push_Back(node->value);node = node->Next;}
}List::List(std::initializer_list<int> initList) : Head(nullptr), Tail(nullptr), size(0)
{for (auto value : initList){Push_Back(value);}
}List::~List()
{Clear();
}bool List::IsEmpty()
{return this->size == 0 ? true : false;
}size_t List::GetSize()
{return this->size;
}void List::Clear()
{if (IsEmpty()) return;Node* node = this->Head;while (node){Node* Temp = node->Next;delete node;node = Temp;}Head = Tail = nullptr;size = 0;
}void List::Push_Back(int value)
{//创建对象时关联前后节点对象Node* node = new Node(value, Tail, nullptr);//当前容器是否存在尾节点if (Tail != nullptr){Tail->Next = node;}//修正尾部节点Tail = node;//判断头部节点if (Head == nullptr){Head = node;}++this->size;
}void List::Push_Front(int value)
{Node* node = new Node(value, nullptr, Head);if (Head != nullptr){Head->Prev = node;}Head = node;if (Tail == nullptr){Tail = node;}++this->size;
}void List::Insert(int InsertValue, int value)
{Node* node = Head;while (node != nullptr && node->value != InsertValue){node = node->Next;}if (node != nullptr){Node* InsertNode = new Node(value, node, node->Next);if (node->Next != nullptr){node->Next->Prev = InsertNode;}else{Tail = InsertNode;}node->Next = InsertNode;++this->size;}}void List::Pop_Back()
{if (Tail == nullptr){return;}//保存尾节点Node* temp = Tail;//修正尾节点Tail = Tail->Prev;if (Tail == nullptr){Head = nullptr;}else{Tail->Next = nullptr;}delete temp;--this->size;
}void List::Pop_Front()
{if (Head == nullptr){return;}Node* temp = Head;Head = Head->Next;if (Head == nullptr){Tail = nullptr;}else{Head->Prev = nullptr;}delete temp;--this->size;
}void List::Remove(int value)
{Node* node = Head;while (node != nullptr && node->value != value){node = node->Next;}if (node != nullptr){if (node == Head) Pop_Front();else if (node == Tail) Pop_Back();else{node->Prev->Next = node->Next;node->Next->Prev = node->Prev;delete node;--this->size;}}}bool List::Find(int value)
{Node* node = Head;while (node != nullptr){if (node->value == value) return true;node = node->Next;}return false;
}List& List::operator=(const List& other)
{if (this != &other){//删除默认数据Clear();Node* node = other.Head;while (node){Push_Back(node->value);node = node->Next;}}return *this;
}int& List::operator[](int Index)
{Node* node = Head;int Count = 0;while (node != nullptr && Count < Index){node = node->Next;++Count;}if (node != nullptr){return node->value;}
}std::ostream& operator<<(std::ostream& output, const List& obj)
{Node* node = obj.Head;while (node != nullptr){output << node->value;if (node->Next != nullptr){output << " | ";}node = node->Next;}return output;
}int main()
{//默认构造函数List myList1;//有参构造函数List myList3(3, 0xCC);//列表构造函数List myList4 = { 1,2,3,4,5 };//拷贝构造函数List myList5 = myList4;//赋值运算符List myList6;myList6 = myList5;std::cout << myList6 << std::endl;return 0;
}
相关文章:

数据结构 - C/C++ - 链表
目录 结构特性 内存布局 结构样式 结构拓展 单链表 结构定义 节点关联 插入节点 删除节点 常见操作 双链表 环链表 结构容器 结构设计 结构特性 线性结构的存储方式 顺序存储 - 数组 链式存储 - 链表 线性结构的链式存储是通过任意的存储单元来存储线性…...

sheng的学习笔记-AI-高斯混合模型(GMM)
AI目录:sheng的学习笔记-AI目录-CSDN博客 需要学习前置知识: 聚类,可参考 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 EM算法,可参考 sheng的学习笔记-AI-EM算法-CSDN博客 贝叶斯,可参考 sheng的学习笔记-AI-…...

OFDM的缺点与关键技术
子载波间干扰英文简写ICI,ICI可能由各种原因引起 在多径信道中,CP小于最大附加时延时收发系统载波频率偏差和采样偏差收发系统相对移动,存在多普勒频移 ICI是制约OFDM系统性能的主要重要因素之一 对频率偏差敏感----->同步技术࿰…...

电脑录音软件哪个好?7款录制音频工具大盘点,赶快学起来!(2024)
也许你渴望提取你最喜欢的节目的背景音乐,或者你希望录制自己的声音制作教程。如果是这样,你就需要一款优秀的电脑录音软件,来帮助你捕捉任何你想要的声音,而且不会损失音质。目前市场上存在着大量的录制音频工具,面对…...
【Android面试八股文】你说你使用Leakcanary进行内存泄漏检测,那你能说一说Leakcanary的原理吗?
文章目录 一、 Java四大引用二、 LeakCanary示例工作机制注意事项三、 Leakcanary的原理四、 Leakcanary的源码分析LeakCanary#Install创建RefWatcherAndroidRefWatcherBuilder#buildAndInstall监听Activity的引用 : ActivityRefWatcher检查引用Dump Heap解析hprof定位泄露的引…...

蒂升电梯职业性格和Verify认知能力SHL测评答题攻略及薪资待遇解密!
一、蒂升电梯职业性格和认知能力测评考什么 您好!蒂升电梯公司邀请您参加的OPQ职业性格测评和Verify认知能力测评是两种常见的评估工具,用于帮助了解个人的职场性格特点和认知能力。 OPQ职业性格测评 这是一种性格测试,通常用于评估个人在…...

window上部署sql server改动端口、和sqlserver的一些还原、批量插入存储过程的命令
1.端口的查看和启动 --windows上安装上sql server数据库后,搜索界面搜索sql,会出现配置管理器,点击进入 --进入后再次选择配置管理器 2. sqlserver数据库还原图形化 sqlserver还原数据库时会使数据库进入一个restore的还原状态,…...

【单片机与嵌入式】stm32串口通信入门
一、串口通信/协议 (一)串口通信简介 串口通信是一种通过串行传输方式在电子设备之间进行数据交换的通信方式。它通常涉及两条线(一条用于发送数据,一条用于接收数据),适用于各种设备,从微控制…...
启动Redis服务器
名人说:一点浩然气,千里快哉风。 ——苏轼 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、在 Linux 或 macOS 上启动 Redis二、在 Windows 上启动 Redis三、配置 Redis 为服务启动&…...
uniapp中使用threejs加载几何体
我的建议是使用这个库 https://github.com/deepkolos/three-platformize 为什么?我试了uniapp推荐的和threejs-miniprogram这个小程序官方库,都加载不出来我的obj模型。所有我推荐不要用obj模型最好,挺多都支持GLTF模型的,但是我不…...
【SQL注入】 数据库基础
MySQL中的库名 information_schema(信息库)—— 保存其他数据库里所有信息(数据库名、表、字段的数据类型/访问权限) mysql—— 存储用户名 密码 host performance_schema——内存数据库 数据放在内存中直接操作的数据库 sys—…...

文件操作~
目录 1.为什么使用文件? 2.什么是文件? 2.1 程序文件 2.2 数据文件 2.3 文件名 3.⼆进制文件和文本文件? 4.文件的打开和关闭 4.1 流和标准流 4.1.1 流 4.1.2 标准流 4.2 文件指针 4.3 ⽂件的打开和关闭 5.文件的顺序读写 5.1 …...

身边的故事(十二):阿文的故事:消失
那以后就再也没有任何阿文的消息。刚开始还打过几次电话,他都没接。后来也就慢慢的淡忘了,为自己的工作生活而奔波,时间冲淡一切。在那几年里,阿文就像消失了一样。直到2021的某一天,电话那端传来了熟悉但是有点陌生的…...
智能扫地机器人程序中出现的问题可以参考的解决方案
在解决智能扫地机器人程序中可能遇到的问题时,可以参考以下分点表示和归纳的解决方案: 环境感知与地图构建 ① 使用先进的传感器技术:如激光雷达、超声波和红外传感器,以提高环境感知的准确性和可靠性。 ② 优化地图构建算法&a…...

如何借用物联网快速实现高标准农田信息化
如何借用物联网快速实现高标准农田信息化 高标准农田信息化,作为现代农业发展的重要基石,是指在建设高产、稳产、节水、环保的农田基础上,深度融合现代信息技术,实现农田管理的精准化、智能化和高效化。物联网(Intern…...
计算机网络基础入门
计算机网络基础入门 目录: 简介网络分层模型数据封装与解封装IP地址与子网掩码网络协议示例代码 1. 简介 计算机网络是指将地理位置不同的多台计算机及外部设备通过通信线路连接起来,实现信息资源共享和信息传递的系统。计算机网络是现代信息社会的基…...
uniApp vue2 vue3配置代理
vue2配置代理 在manifest.json中增加如下配置 "h5" : {"router" : {"mode" : "history"},"devServer" : {"disableHostCheck" : true,"proxy" : {"/api" : {"target" : "请…...

运维锅总详解RocketMQ
本文尝试从Apache RocketMQ的简介、主要组件及其作用、3种部署模式、Controller集群模式工作流程、最佳实践等方面对其进行详细分析。希望对您有所帮助! 一、Apache RocketMQ 简介 Apache RocketMQ 是一个开源的分布式消息中间件,由阿里巴巴集团开发并…...

【Linux】使用ntp同步时间
ntp介绍 NTP(Network Time Protocol,网络时间协议)是一种用于同步计算机时间的协议,工作在UDP的123端口上。它是一种客户端-服务器协议,用于同步计算机的时钟。通过连接到网络上的时间服务器,计算机可以获…...

【FedMut】Generalized Federated Learning via Stochastic Mutation
基于随机变异的泛化联邦学习 来源:AAAI2024 Abstract 问题: FedAvg 将相同的全局模型派发给客户端进行本地训练,容易陷入尖锐解,导致训练出性能低下的全局模型 提出 FedMut: 本文提出了一种名为 FedMut 的新型FL方法…...

GC1808:高性能24位立体声音频ADC芯片解析
1. 芯片简介 GC1808 是一款24位立体声音频模数转换器(ADC),支持96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于家庭影院、蓝牙音箱等场景。 核心特性 高精度:24位分辨率,…...
Unity——QFramework框架 内置工具
QFramework 除了提供了一套架构之外,QFramework 还提供了可以脱离架构使用的工具 TypeEventSystem、EasyEvent、BindableProperty、IOCContainer。 这些工具并不是有意提供,而是 QFramework 的架构在设计之初是通过这几个工具组合使用而成的。 内置工具…...
html、css(javaweb第一天)
HTML: 文字、图片、视频组成 由标签组成的语言 行内标签span//无语意 <img src"url">//图片 <a herf"url" target"是否开新页面">点击谁</a>//超链接 <video src"url" controls></video>//controls播放…...
Go语言进阶④:Go的数据结构和Java的有啥不一样
Go语言进阶④:数据结构大冒险! ——写惯了 Java 的你,看 Go 的容器世界会头皮发麻吗? 一、写在前面:Java 程序员的容器情怀 在 Java 世界,你可能习惯了满手的 ArrayList、HashMap、Set、Queue 等容器类,配合着各种范型、接口和 Lambda 表达式,写得风生水起。 可一到…...

《影像引导下骨盆创伤手术的术前骨折复位规划:基于学习的综合流程》|文献速递-深度学习医疗AI最新文献
Title 题目 Preoperative fracture reduction planning for image-guided pelvic trauma surgery: A comprehensive pipeline with learning 《影像引导下骨盆创伤手术的术前骨折复位规划:基于学习的综合流程》 01 文献速递介绍 《影像引导下骨盆创伤手术的术前…...

“一代更比一代强”:现代 RAG 架构的演进之路
编者按: 我们今天为大家带来的文章,作者的观点是:RAG 技术的演进是一个从简单到复杂、从 Naive 到 Agentic 的系统性优化过程,每一次优化都是在试图解决无数企业落地大语言模型应用时出现的痛点问题。 文章首先剖析 Naive RAG 的基…...
【强化学习】——03 Model-Free RL之基于价值的强化学习
【强化学习】——03 Model-Free RL之基于价值的强化学习 \quad\quad \quad\quad 动态规划算法是基于模型的算法,要求已知状态转移概率和奖励函数。但很多实际问题中环境 可能是未知的,这就需要不基于模型(Model-Free)的RL方法。 \quad\quad 其又分为: 基于价值(Valu…...

[ Qt ] | 与系统相关的操作(三):QFile介绍和使用
目录 之前的操作文件的方式 Qt中的文件操作简介 QFile 打开 读 写 关闭 一个例子来说明 QFileInfo 之前的操作文件的方式 C语言中,fopen 打开文件,fread fwrite 读写文件,fclose 关闭文件。 C中,fstream 打开文件&…...
Android动态广播注册收发原理
一、动态广播的注册流程 1. 注册方式 动态广播通过代码调用 Context.registerReceiver() 方法实现,需显式指定 IntentFilter 和接收器实例: // 示例:在 Activity 中注册监听网络变化的广播 IntentFilter filter new IntentFilter…...

Ubuntu 系统部署 MySQL 入门篇
一、安装 MySQL 1.1 更新软件包 在终端中执行以下命令,更新系统软件包列表,确保安装的是最新版本的软件: sudo apt update 1.2 安装 MySQL 执行以下命令安装 MySQL 服务端: sudo apt install mysql-server 在安装过程中&…...