P1【知识点】【数据结构】【链表LinkedList】C++版

链表是一种逻辑上连续,内存上分散的线性表数据结构,是用一组任意的空间(可以连续,也可以不连续)来存放数据元素。每个数据元素成为一个”结点“,每个结点由数据域和指针域组成。

  1. 访问元素(Access)O(N)
  2. 搜索元素(Search)O(N)
  3. 插入元素(Insert)O(1)
  4. 删除元素(Delete)O(1)

特点:写的快读的慢(应用于写多读少)

最基本的链表如图所示:

以下参考:数据结构:链表及其C++实现 - 菜鸡刘 - 博客园 (cnblogs.com)

插入操作:

假如需要在C结点后面插入F结点,只需要使C结点的指针指向F,F结点的指针指向结点D即可,如图所示

需要注意的是,在具体实现的时候,需要先暂存C结点的指针,先将其赋值给F结点指针,然后再将F结点的地址赋值给C结点的指针,否则会丢失D结点的地址,链表就会在此处断开。

删除操作:

假如需要删除D结点,则直接让C结点的指针指向E结点即可,如图所示

具体代码实现:

本文利用C++面向对象的特性与模板实现了一个链表类,并实现了插入、删除、查找、拷贝构造、拷贝赋值等基本操作。

结点类实现:
// 链表节点类
template<typename T>
class node
{
public:
    node() : next(nullptr){} // 这是构造函数
    node(T val) : data(val), next(nullptr) {} // 这是有参构造
private:
    T data;
    node* next;
    friend class list<T>; //同时在node类中将链表类list声明为友元,便于访问node的成员。
};
链表类声明:

链表类list的声明如下,主要实现了以下操作。list类包含两个成员属性head_ptr和length,前者是链表的头指针,后者储存链表的长度。

template<typename T>
class list
{
public:
    list(); // 构造函数
    list(const list<T>& l); // 拷贝构造
    list<T>& operator= (const list<T>& l); // 拷贝赋值 
    void insert_node(int index, T val); // 在index处插入结点
    void del_node(int index); // 删除index处结点
    T get_node(int index); // 获取index处结点值
    int find(int value); // 查找值value,找到返回index,找不到返回-1
    int get_length(); // 获取链表长度
    void push_back(T val); // 在链表尾部插入数据
    ~list(); // 析构函数

private:
    node<T>* head_ptr; // 链表头指针
    int length; // 链表长度
};
插入实现:

对于插入操作,本文将其分为了三种情况

  • 超出索引,抛出异常
  • 插在空链表的头
  • 一般情况

// 在index处插入结点
template<typename T>
void list<T>::insert_node(int index, T val)
{
    if((index > this->length)) // 超过索引,最多可以插到当前结点的下一个结点,否则就是超过索引
    {
        throw runtime_error("index out of this list`s range");
    }
    else if((this->head_ptr == nullptr) && (index == 0)) // 插在空链表的头
    {
        this->head_ptr = new node<T>;
        this->head_ptr->next = nullptr;
        this->head_ptr->data = val;
        this->length++;
    } 
    else // 一般情况
    {
        node<T>* p1 = this->head_ptr;
        node<T>* p2 = new node<T>;
        for(int i = 0; i < index - 1; i++)
        {
            p1 = p1->next;
        }
        p2->data = val;
        p2->next = p1->next;
        p1->next = p2;
        this->length++;
    }
}
删除实现:

删除操作需要注意的是,每个结点都是通过new在堆区申请的内存,因此删除节点需要手动释放其内存。

// 删除index处结点
template<typename T>
void list<T>::del_node(int index)
{
    node<T>* p1 = this->head_ptr;
    node<T>* p2 = nullptr;
    for(int i = 0; i < index - 1; i++)
    {
        p1 = p1->next;
    }
    p2 = p1->next->next;
    delete p1->next;
    p1->next = p2;
    this->length--;
}
索引实现:
// 获取index处结点值
template<typename T>
T list<T>::get_node(int index)
{
    if(index > this->length - 1) // 超过索引
    {
        throw runtime_error("index out of this list`s range");
    }
    
    node<T>* p1 = this->head_ptr;
    for(int i = 0; i < index; i++)
    {
        p1 = p1->next;
    }

    return p1->data;
}
查找实现:
// 查找值value,找到返回index,找不到返回-1
template<typename T>
int list<T>::find(int value)
{
    node<T>* p1 = this->head_ptr;
    for(int i = 0; i < this->length; i++)
    {
        if(p1->data == value)
        {
            return i;
        }
        p1 = p1->next;
    }

    return -1;
}
析构实现:

析构函数需要做的就是释放链表每个节点的内存。

// 析构函数
template<typename T>
list<T>::~list()
{
    // 清空链表
    node<T>* p1 = this->head_ptr;
    node<T>* p2 = p1->next;
    while(p2 != nullptr)
    {
        delete p1;
        p1 = p2;
        p2 = p2->next;
    }
    delete p1;
    this->length = 0;
    this->head_ptr = nullptr;

} 

力扣练习:

【203】移除链表元素

【206】反转链表

视频来源:【数据结构2】链表Linkedlist_哔哩哔哩_bilibili 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

特征融合篇 | YOLOv8改进之引入轻量级跨尺度特征融合模块CCFM | 源自RT-DETR

前言:Hello大家好,我是小哥谈。CCFM(Cross-Scale Feature Fusion Module)即为跨尺度特征融合模块。这个模块的作用是将不同尺度的特征通过融合操作整合起来,以增强模型对于尺度变化的适应性和对小尺度对象的检测能力。CCFM可以有效地整合细节特征和上下文信息,从而提高模…

【全开源】简单商城系统(PC/UniAPP)

轻松构建您的在线商店 在当今数字化时代&#xff0c;拥有一个在线商店对于许多商家来说已成为必不可少的营销手段。为了满足这一需求&#xff0c;我们推出了“简单商城系统源码”&#xff0c;让您轻松构建并管理您的在线商店。 一、简单易用&#xff0c;快速上手 “简单商城…

python demo

文章背景&#xff0c;记录python 小demo 集合 1、使用python matplotlib库描绘曲线 import matplotlib.pyplot as NLAx_index [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100] y_index [6.1, 7.4, 9.1, 11.1, 12.69, 14.35, 16.1, 1…

成都爱尔周进院长提醒当双眼度数差距过大,我们该做些什么

每个人的用眼方式、用眼习惯且两只眼睛“天生条件”不一定相同&#xff0c;当发生近视&#xff0c;双眼近视程度也就可能不同&#xff0c;双眼度数必然会变得不一样。当双眼度数产生差异&#xff0c;尤其是当双眼度数差别过大时会引发哪些问题&#xff1f; 双眼度数不一致&…

面试八股之MySQL篇4——事务篇

&#x1f308;hello&#xff0c;你好鸭&#xff0c;我是Ethan&#xff0c;一名不断学习的码农&#xff0c;很高兴你能来阅读。 ✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。 &#x1f3c3;人生之义&#xff0c;在于追求&#xff0c;不在成败&#xff0c;勤通…

【ARFoundation自学03】AR Point Cloud 点云(参考点标记)功能详解

和平面识别框架一样 1为XR Origin添加AR Point Cloud Manager组件 然后你的ar应用就具备了点云识别功能&#xff0c;就这么简单 2.可视化这些云点 创建一个美术效果的预制体&#xff0c;人家提供了预设模板 然后拖到仓库&#xff08;ASSETS&#xff09;创建预制体&#xff…

Redis持久化之☞AOF、AOF是怎样执行持久化的?

AOF持久化机制&#xff1a; AOF&#xff08;Append Of File&#xff09;&#xff1a;将redis执行过的所有写指令记录下来&#xff0c;在下次redis重新启动时&#xff0c;只要把这些指令从前到后重复执行一遍&#xff0c;就可以实现数据恢复了。 以独立日志的方式记录每次写命…

本特利330878-90-00前置传感器在PLC系统中的应用与优势

本特利330878-90-00前置传感器在PLC系统中的应用与优势 一、引言 在现代工业自动化领域中&#xff0c;传感器作为信息获取的重要工具&#xff0c;其性能的稳定性和准确性直接影响到整个系统的运行效率。其中&#xff0c;本特利330878-90-00前置传感器以其卓越的性能和广泛的应…

查看主机的php参数short_open_tag 是否为 on

我想要查看主机的php参数short_open_tag 是否为 on&#xff0c;由于我使用的是Hostease的Linux虚拟主机产品&#xff0c;在cPanel面板中并没有找到这个参数选项&#xff0c;因此无法查看。这边联系了Hostease技术支持了解&#xff0c;可以通过以下方式进行查看。 1.先登陆cPane…

自定义横向思维导图,横向组织架构图,横向树图。可以自定义节点颜色,样式,还可以导出为图片

最近公司设计要求根据目录结构&#xff0c;横向展示。所以做了一个横向的思维导图&#xff0c;横向的树结构&#xff0c;横向的组织架构图&#xff0c;可以自定义节点颜色&#xff0c;样式&#xff0c;还可以导出为图片 话不多说&#xff0c;直接上图片&#xff0c;这个就是一…

nssctf(Web刷题)

[SWPUCTF 2021 新生赛]gift_F12 打开题目是一个时间页面&#xff0c;不过看了一会儿发现没有什么用 直接F12打开网页源代码 CtrlF搜索flag 找到了flag NSSCTF{We1c0me_t0_WLLMCTF_Th1s_1s_th3_G1ft} [第五空间 2021]签到题 NSSCTF{welcometo5space} [SWPUCTF 2021 新生赛…

cPanel中如何为数据库添加用户权限

本周有一个客户&#xff0c;购买Hostease的主机&#xff0c;询问我们的在线客服&#xff0c;他的网站安装后再还是无法访问。 客户购买的是Linux虚拟主机&#xff0c;带cPanel面板的。网站访问有如下数据库连接错误: 随后检查发现客户创建的数据库没有添加数据库用户权限。 下面…

期权策略交易怎么做?怎么选择期权策略?

今天期权懂带你了解期权策略交易怎么做&#xff1f;怎么选择期权策略&#xff1f;期权交易是一种金融衍生品交易方式&#xff0c;它给予购买者在未来特定时间内以特定价格购买&#xff08;或出售&#xff09;标的资产的权利。 期权策略交易怎么做&#xff1f; 配对看跌期权&am…

基于地理坐标的高阶几何编辑工具算法(3)——相离面吸附

文章目录 工具步骤应用场景算法输入算法输出算法示意图算法原理 工具步骤 点击面&#xff0c;点击“相离面吸附”工具&#xff0c;绘制一个面&#xff0c;双击结束后&#xff0c;与所有相交的面进行吸附 应用场景 为了让相离的两个几何面在空间上相邻&#xff0c;使用该工具…

llama_factory的使用

1.git clone llama_factory到本地 2.记得安环境&#xff0c;在clone后 3.多显卡要设置一下 4.数据文件放在data里面&#xff0c;仿照模板里的格式 5.进入llama_factory微调页面 python src/webui.py 6.llama_factory介绍&#xff1a;10分钟打造你个人专属的语言大模型&am…

离散数学--图论

目录 1.简单概念 2.握手定理 3.点割集 4.边割集 5.点连通度和边连通度 6.Dijstra算法&&最短路径 7.有向图的连通性 8.图的矩阵表示 9.欧拉图问题 10.哈密尔顿图 1.简单概念 &#xff08;1&#xff09;这个里面的完全图比较重要&#xff0c;完全图是例如k3,k5这…

GPT-SoVITS语音克隆部署与使用

GPT-SoVITS是一款强大的少量样本语音转换与语音合成开源工具。当前&#xff0c;GPT-SoVITS实现了如下几个方面的功能&#xff1a; 由参考音频的情感、音色、语速控制合成音频的情感、音色、语速可以少量语音微调训练&#xff0c;也可不训练直接推理可以跨语种生成&#xff0c;…

00-Vue的介绍和vue-cli

前言Vue的介绍和vue-cli一、发展历史相关网址介绍Vue框架的特点 二、Vue 的环境搭建1&#xff0c;卸载掉所有已经存在的所有Node.js版本2&#xff0c;下载MVM包4、安装node.js5、常见的插件 三、利用 vue-cli 新建一个空的项目1、官方代码参考2、安装 vue-cli&#xff08;命令行…

【C++】学习笔记——map和set

文章目录 十五、map和set1. 关联式容器2. set的介绍3. set的使用4. multiset5. map的介绍6. map的使用7. multimap8. map中重载的operator[] 未完待续 十五、map和set 1. 关联式容器 我们已经接触过STL中的部分容器&#xff0c;比如&#xff1a;vector 、list 、deque 等&…

04. Redis 配置文件

文章目录 单位包含网络 NETWORK通用 GENERAL快照 SNAPSHOTTING主从复制 REPLICATION安全 SECURITY客户端 CLIENTS内存设置 MEMORY MANAGEMENTAPPEND ONLY MODE 模式&#xff08;aof 的配置&#xff09; 单位 配置文件对大小写不敏感&#xff08;unit单位&#xff09;。 包含 …