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

数据结构 - 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目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 需要学习前置知识&#xff1a; 聚类&#xff0c;可参考 sheng的学习笔记-AI-聚类(Clustering)-CSDN博客 EM算法&#xff0c;可参考 sheng的学习笔记-AI-EM算法-CSDN博客 贝叶斯&#xff0c;可参考 sheng的学习笔记-AI-…...

OFDM的缺点与关键技术

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

电脑录音软件哪个好?7款录制音频工具大盘点,赶快学起来!(2024)

也许你渴望提取你最喜欢的节目的背景音乐&#xff0c;或者你希望录制自己的声音制作教程。如果是这样&#xff0c;你就需要一款优秀的电脑录音软件&#xff0c;来帮助你捕捉任何你想要的声音&#xff0c;而且不会损失音质。目前市场上存在着大量的录制音频工具&#xff0c;面对…...

【Android面试八股文】你说你使用Leakcanary进行内存泄漏检测,那你能说一说Leakcanary的原理吗?

文章目录 一、 Java四大引用二、 LeakCanary示例工作机制注意事项三、 Leakcanary的原理四、 Leakcanary的源码分析LeakCanary#Install创建RefWatcherAndroidRefWatcherBuilder#buildAndInstall监听Activity的引用 : ActivityRefWatcher检查引用Dump Heap解析hprof定位泄露的引…...

蒂升电梯职业性格和Verify认知能力SHL测评答题攻略及薪资待遇解密!

​一、蒂升电梯职业性格和认知能力测评考什么 您好&#xff01;蒂升电梯公司邀请您参加的OPQ职业性格测评和Verify认知能力测评是两种常见的评估工具&#xff0c;用于帮助了解个人的职场性格特点和认知能力。 OPQ职业性格测评 这是一种性格测试&#xff0c;通常用于评估个人在…...

window上部署sql server改动端口、和sqlserver的一些还原、批量插入存储过程的命令

1.端口的查看和启动 --windows上安装上sql server数据库后&#xff0c;搜索界面搜索sql&#xff0c;会出现配置管理器&#xff0c;点击进入 --进入后再次选择配置管理器 2. sqlserver数据库还原图形化 sqlserver还原数据库时会使数据库进入一个restore的还原状态&#xff0c;…...

【单片机与嵌入式】stm32串口通信入门

一、串口通信/协议 &#xff08;一&#xff09;串口通信简介 串口通信是一种通过串行传输方式在电子设备之间进行数据交换的通信方式。它通常涉及两条线&#xff08;一条用于发送数据&#xff0c;一条用于接收数据&#xff09;&#xff0c;适用于各种设备&#xff0c;从微控制…...

启动Redis服务器

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、在 Linux 或 macOS 上启动 Redis二、在 Windows 上启动 Redis三、配置 Redis 为服务启动&…...

uniapp中使用threejs加载几何体

我的建议是使用这个库 https://github.com/deepkolos/three-platformize 为什么&#xff1f;我试了uniapp推荐的和threejs-miniprogram这个小程序官方库&#xff0c;都加载不出来我的obj模型。所有我推荐不要用obj模型最好&#xff0c;挺多都支持GLTF模型的&#xff0c;但是我不…...

【SQL注入】 数据库基础

MySQL中的库名 information_schema&#xff08;信息库&#xff09;—— 保存其他数据库里所有信息&#xff08;数据库名、表、字段的数据类型/访问权限&#xff09; mysql—— 存储用户名 密码 host performance_schema——内存数据库 数据放在内存中直接操作的数据库 sys—…...

文件操作~

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

身边的故事(十二):阿文的故事:消失

那以后就再也没有任何阿文的消息。刚开始还打过几次电话&#xff0c;他都没接。后来也就慢慢的淡忘了&#xff0c;为自己的工作生活而奔波&#xff0c;时间冲淡一切。在那几年里&#xff0c;阿文就像消失了一样。直到2021的某一天&#xff0c;电话那端传来了熟悉但是有点陌生的…...

智能扫地机器人程序中出现的问题可以参考的解决方案

在解决智能扫地机器人程序中可能遇到的问题时&#xff0c;可以参考以下分点表示和归纳的解决方案&#xff1a; 环境感知与地图构建 ① 使用先进的传感器技术&#xff1a;如激光雷达、超声波和红外传感器&#xff0c;以提高环境感知的准确性和可靠性。 ② 优化地图构建算法&a…...

如何借用物联网快速实现高标准农田信息化

如何借用物联网快速实现高标准农田信息化 高标准农田信息化&#xff0c;作为现代农业发展的重要基石&#xff0c;是指在建设高产、稳产、节水、环保的农田基础上&#xff0c;深度融合现代信息技术&#xff0c;实现农田管理的精准化、智能化和高效化。物联网&#xff08;Intern…...

计算机网络基础入门

计算机网络基础入门 目录&#xff1a; 简介网络分层模型数据封装与解封装IP地址与子网掩码网络协议示例代码 1. 简介 计算机网络是指将地理位置不同的多台计算机及外部设备通过通信线路连接起来&#xff0c;实现信息资源共享和信息传递的系统。计算机网络是现代信息社会的基…...

uniApp vue2 vue3配置代理

vue2配置代理 在manifest.json中增加如下配置 "h5" : {"router" : {"mode" : "history"},"devServer" : {"disableHostCheck" : true,"proxy" : {"/api" : {"target" : "请…...

运维锅总详解RocketMQ

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

【Linux】使用ntp同步时间

ntp介绍 NTP&#xff08;Network Time Protocol&#xff0c;网络时间协议&#xff09;是一种用于同步计算机时间的协议&#xff0c;工作在UDP的123端口上。它是一种客户端-服务器协议&#xff0c;用于同步计算机的时钟。通过连接到网络上的时间服务器&#xff0c;计算机可以获…...

【FedMut】Generalized Federated Learning via Stochastic Mutation

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

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

循环冗余码校验CRC码 算法步骤+详细实例计算

通信过程&#xff1a;&#xff08;白话解释&#xff09; 我们将原始待发送的消息称为 M M M&#xff0c;依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)&#xff08;意思就是 G &#xff08; x ) G&#xff08;x) G&#xff08;x) 是已知的&#xff09;&#xff0…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

浅谈不同二分算法的查找情况

二分算法原理比较简单&#xff0c;但是实际的算法模板却有很多&#xff0c;这一切都源于二分查找问题中的复杂情况和二分算法的边界处理&#xff0c;以下是博主对一些二分算法查找的情况分析。 需要说明的是&#xff0c;以下二分算法都是基于有序序列为升序有序的情况&#xf…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

云安全与网络安全:核心区别与协同作用解析

在数字化转型的浪潮中&#xff0c;云安全与网络安全作为信息安全的两大支柱&#xff0c;常被混淆但本质不同。本文将从概念、责任分工、技术手段、威胁类型等维度深入解析两者的差异&#xff0c;并探讨它们的协同作用。 一、核心区别 定义与范围 网络安全&#xff1a;聚焦于保…...

sshd代码修改banner

sshd服务连接之后会收到字符串&#xff1a; SSH-2.0-OpenSSH_9.5 容易被hacker识别此服务为sshd服务。 是否可以通过修改此banner达到让人无法识别此服务的目的呢&#xff1f; 不能。因为这是写的SSH的协议中的。 也就是协议规定了banner必须这么写。 SSH- 开头&#xff0c…...