数据结构 - 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;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38824.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

技术分享:分布式数据库DNS服务器的架构思路

DNS是企业数字化转型的基石。伴随微服务或单元化部署的推广&#xff0c;许多用户也开始采用分布式数据库将原来的单体数据库集群服务架构拆分为大量分布式子服务集群&#xff0c;对应不同的微服务或服务单元。本文将从分布式数据库DNS服务器的架构需求、架构分析两方面入手&…

湖北大学2024年成人高考函授报名专升本市场营销专业介绍

在璀璨的学术殿堂中&#xff0c;湖北大学如同一颗璀璨的明珠&#xff0c;熠熠生辉。为了满足广大社会人士对于继续深造、提升自我、实现职业梦想的渴望&#xff0c;湖北大学特别开设了成人高等继续教育项目&#xff0c;为广大有志之士敞开了一扇通往知识殿堂的大门。 而今&…

【FFmpeg】av_write_frame函数

目录 1.av_write_frame1.1 写入pkt&#xff08;write_packets_common&#xff09;1.1.1 检查pkt的信息&#xff08;check_packet&#xff09;1.1.2 准备输入的pkt&#xff08;prepare_input_packet&#xff09;1.1.3 检查码流&#xff08;check_bitstream&#xff09;1.1.4 写入…

【创建者模式-建造者模式】

概要 将一个复杂对象的构建与表示分离&#xff0c;使得同样的构建过程可以创建不同的表示。 建造者模式包含以下角色 抽象建造者类&#xff08;Builder&#xff09;&#xff1a;这个接口规定要实现复杂对象的那些部分的创建&#xff0c;并不涉及具体的部件对象的创建。具体建…

在WSL Ubuntu中启用root用户的SSH服务

在 Ubuntu 中&#xff0c;默认情况下 root 用户是禁用 SSH 登录的&#xff0c;这是为了增加系统安全性。 一、修改配置 找到 PermitRootLogin 行&#xff1a;在文件中找到 PermitRootLogin 配置项。默认情况下&#xff0c;它通常被设置为 PermitRootLogin prohibit-password 或…

一篇文章学会【node.js安装以及Vue-Cli脚手架搭建】

一.为什么搭建Vue-Cli (1).传统的前端项目结构&#xff1a; 一个项目中有许多html文件&#xff0c;每一个html文件都是相互独立的&#xff0c; 如果需要在页面中导入一些外部依赖的组件&#xff0c;就需要在每一个html文件中都需要导入&#xff0c;非常麻烦 (2).现在的前端…

A股低开高走,近3000点,行情要启动了吗?

A股低开高走&#xff0c;近3000点&#xff0c;行情要启动了吗&#xff1f; 今天的A股&#xff0c;让人瞪目结舌了&#xff0c;你们知道是为什么吗&#xff1f;盘面上出现2个重要信号&#xff0c;一起来看看&#xff1a; 1、今天两市低开高走&#xff0c;银行板块护盘指数&…

盘古5.0,靠什么去解最难的题?

文&#xff5c;周效敬 编&#xff5c;王一粟 当大模型的竞争开始拼落地&#xff0c;商业化在B端和C端都展开了自由生长。 在B端&#xff0c;借助云计算向千行万业扎根&#xff1b;在C端&#xff0c;通过软件App和智能终端快速迭代。 在华为&#xff0c;这家曾经以通信行业起…

Error: A JNl error has occurred, please check your installation and try again.

Eclipse 运行main方法的时候报错&#xff1a;Error: A JNl error has occurred, please check your installation and try again. 一、问题分析 导致这个问题&#xff0c;主要原因&#xff0c;我认为是在新版本中&#xff0c;默认的JDK编译版本与我们配置的JDK版本不一致导致的…

公网环境使用Potplayer远程访问家中群晖NAS搭建的WebDAV听歌看电影

文章目录 前言1 使用环境要求&#xff1a;2 配置webdav3 测试局域网使用potplayer访问webdav4 内网穿透&#xff0c;映射至公网5 使用固定地址在potplayer访问webdav 前言 本文主要介绍如何在Windows设备使用potplayer播放器远程访问本地局域网的群晖NAS中的影视资源&#xff…

告别流失,拥抱增长!Xinstall智能邀请系统,让你的App拉新更高效

在移动互联网时代&#xff0c;App的推广和运营面临着诸多挑战。其中&#xff0c;如何有效地进行邀请拉新活动&#xff0c;吸引更多新用户&#xff0c;成为了每个运营者都需要面对的问题。今天&#xff0c;我们将为大家介绍一款能够帮助你轻松解决这一难题的神器——Xinstall。 …

互联网框架五层模型详解

注&#xff1a;机翻&#xff0c;未校对。 What is the Five Layers Model? The Framework of the Internet Explained 五层模型互联网框架解释 Computer Networks are a beautiful, amazing topic. Networks involve so much knowledge from different fields, from physics…

[数据集][目标检测]城市街道井盖破损未盖丢失检测数据集VOC+YOLO格式4404张5类别

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

昇思25天学习打卡营第03天 | 张量 Tensor

昇思25天学习打卡营第03天 | 张量 Tensor 文章目录 昇思25天学习打卡营第03天 | 张量 Tensor张量张量的创建张量的属性Tensor与NumPy转换稀疏张量CSRTensorCOOTensor 总结打卡 张量 张量&#xff08;Tensor&#xff09;是一种类似于数组和矩阵的特殊数据结构&#xff0c;是神经…

MATLAB|更改绘图窗口的大小和位置

MATLAB绘图 plot、plot3、cdfplot都适用 效果 如下图&#xff0c;运行程序后可以直接得到这两个绘图窗口。 右上角的Figure1是原始图片&#xff0c;右下角的Figure2是调整了位置和大小后的绘图窗口。 完整源代码 % 绘图大小和位置调整 % Evand©2024 % 2024-7-1/Ver1…

Transformer模型原理细节解析

基本原理: Transformer 的核心概念是 自注意力机制(Self-Attention Mechanism),它允许模型在处理每个输入时“关注”输入序列的不同部分。这种机制让模型能够理解每个单词或符号与其他单词或符号之间的关系,而不是逐个地线性处理输入。 Transformer 主要由两个部分组成:…

手把手教你搭建PyTorch环境:MindStudio中PyTorch模型开发实战

本次实验的视频链接如下&#xff1a;​https://www.bilibili.com/video/BV1iA4y1f7o1/ 本次实验在MindStudio上进行&#xff0c;请先按照 教程 配置环境,安装MindStudio。 ​ MindStudio的是一套基于华为自研昇腾AI处理器开发的AI全栈开发工具平台&#xff0c;该IDE上功能很多…

ESOP 系统助力电子设备公司的管理模式升级

在科技飞速发展的时代&#xff0c;电子设备行业竞争愈发激烈&#xff0c;企业要想在市场中立足并持续发展&#xff0c;不断升级管理模式成为关键。ESOP系统的引入&#xff0c;为电子设备公司带来了全新的机遇&#xff0c;有力地推动了管理模式的升级。 ESOP 系统首先为电子设备…

element el-table表格切换分页保留分页数据+限制多选数量

el-table表格并没有相关的方法来禁用表头里面的多选按钮 那么我们可以另辟蹊径&#xff0c;来实现相同的多选切换分页&#xff08;保留分页数据&#xff09; 限制多选数量的效果 <el-table:data"tableData"style"width: 100%">// 不使用el-talbe自带…

农村程序员陈随易2024年中总结

今天是 2024年7月1日&#xff0c;时间如白驹过隙&#xff0c;今年已去其一半。 总结一下今年上半年的情况&#xff0c;给大家提供一些参考和建议。 希望大家关注一下公众号 陈随易&#xff0c;有些内容只在公众号发表。 先看看我的年初计划&#xff0c;这个在今年年初的时候&…