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

news2024/12/24 10:07:02

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

  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 

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

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

相关文章

RK3588 Android13 TvSetting 中增加字体大小调整菜单

前言 电视产品,客户要求在设置中设备偏好设置子菜单里的显示和声音二级菜单里增加字体大小菜单功能, 其实里面本来有个文字缩放菜单,但不满足客户需求,那就新加一个也不是什么难事,开整。 效果图 TvSetting 部分修改文件清单 packages/apps/TvSettings/Settings/res/va…

解锁 user-agent(UA)识别 Api 接口的无限潜力

近年来&#xff0c;随着移动设备的普及和互联网的迅猛发展&#xff0c;用户使用不同的操作系统、浏览器以及硬件设备来访问网页的情况越来越多样化。为了更好地了解用户的访问环境和提供更好的用户体验&#xff0c;我们需要通过用户的访问UA&#xff08;User-Agent&#xff09;…

指针,指针变量,引用,取地址符,malloce()函数使用,C中“—>” 和“ . ” 作用与区别

目录 一&#xff1a;指针,指针变量&#xff0c;引用&#xff0c;取地址符&#xff1a; 前提 &#xff1a; 1.“ * ” 的两种用途 2." & “的两种用途 2.1&#xff1a;引用 2.2&#xff1a;取地址 补充&#xff1a; 二 : malloc(),动态申请地址空间 1.原型定义…

IEEE Transactions on Neural Networks and Learning Systems神经网络和学习系统TNNLS论文投稿须知

一、TNNLS介绍 IEEE Transactions on Neural Networks and Learning Systems作为控制领域的TOP期刊&#xff0c;2024年5月影响因子为10.4&#xff0c;虽然有些下降&#xff0c;之前五年平均影响因子为11.2&#xff0c;但依然是该领域王牌期刊&#xff0c;接收关于神经网络和相…

Python踩坑系列之使用redis报错:module ‘redis‘ has no attribute ‘Redis‘问题

一步一步往后看哦&#xff01;&#xff01;&#xff01; 纳尼&#xff0c;大伙看看这是什么情况&#xff0c;都是这么写的呢&#xff0c;为啥我这就报错了0.0 出现问题不可怕&#xff0c;解决它就完事了。 方法一、安装redis重新运行程序 pip install redis 无果&#xff0…

【kubernetes】探索k8s集群中kubectl的陈述式资源管理

目录 一、k8s集群资源管理方式分类 1.1陈述式资源管理方式&#xff1a;增删查比较方便&#xff0c;但是改非常不方便 1.2声明式资源管理方式&#xff1a;yaml文件管理 二、陈述式资源管理方法 2.1查看版本信息 2.2查看资源对象简写 2.3配置kubectl自动补全 2.4node节点…

10 - 核心对象 Switch / case

简介 在Kettle&#xff08;也称为Pentaho Data Integration&#xff0c;PDI&#xff09;中&#xff0c;Switch/Case 是一个关键的组件&#xff0c;用于根据特定条件将数据流分支到不同的路径。Switch组件评估输入数据中的某个字段&#xff0c;并将数据标记后传递给相应的Case组…

一款数字化管理平台源码:云MES系统(附架构图、流程)技术架构:springboot + vue-element-plus-admin

制造生产企业打造数字化生产管控的系统&#xff0c;从原材料、生产报工、生产过程、质检、设备、仓库等整个业务流程的管理和控制&#xff0c;合理安排生产计划、实时监控生产、优化生产工艺、降低不良产出和运营成本&#xff1b; 技术架构&#xff1a;springboot vue-elemen…

LLaMa系列模型详解(原理介绍、代码解读):LLaMA 3

LLaMA 3 2024年4月18日&#xff0c;Meta 重磅推出了Meta Llama 3&#xff0c;Llama 3是Meta最先进开源大型语言模型的下一代&#xff0c;包括具有80亿和700亿参数的预训练和指令微调的语言模型&#xff0c;能够支持广泛的应用场景。这一代Llama在一系列行业标准基准测试中展示…

UI问题 --- CardView和其它的控件在同一布局中时,始终覆盖其它控件

原本代码&#xff1a; <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"40dp"android:layout_height"wrap_content"andr…

【Vue3】env环境变量的配置和使用(区分cli和vite)

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、env文件二、vue3cli加载env1..env配置2..dev配置&#xff08;其他环境参考&#xff09;3.package.json文件4.使用 三、vue3vite加载e…

MobaXterm使用私钥远程登陆linux

秘钥的形式使用MobaXterm 远程连接 linux 服务器 MobaXterm使用私钥远程登陆linux just填写远程主机 不指定用户 勾选使用私钥 选择私钥即可 1.使用秘钥连接 远程linux 服务器的好处 只需要第一次添加秘钥&#xff0c;并输入密码后&#xff0c;以后再连接就不需要再输入密码…

5款网页表白代码5(附带源码)

5款网页表白代码5 前言效果图及部分源码1.博客式表白2.故事式表白3.信封式表白4.信封式表白&#xff08;简洁版&#xff09;5.高级UI表白页 领取源码下期更新预报 前言 大部分人都有喜欢的人&#xff0c;学会这些表白代码&#xff0c;下次表白你肯定会成功。希望你有个女朋友 …

二叉树遍历操作详解

目录 一、思路详解 1.1 递归思路 1.2 递归分支图 1.3 递归栈帧图 二、C语言实现 2.1 前序遍历 2.2 中序遍历 2.3 后序遍历 三、查找值为x的结点 3.1 递归思路 3.2 C语言代码 一、思路详解 采用递归的思想解决问题&#xff0c;以高度为3的满二叉树为例。 1.1 递归思…

vscode更改语言,记录一下

首先打开安装好的Vscode软件&#xff0c;可以看到页面上显示的是英文效果。 同时按键ctrlshiftp&#xff0c;接着在输入框中输入 configure Display language如图&#xff1a; 选择中文简体就ok了&#xff0c;如果没有则安装 chinese Language pack

Qt QString详细用法

一.基础用法 1.创建QString对象 QString str1 "Hello, World!"; QString str2("This is a QString object."); //一个是等号的重载&#xff0c;一个是拷贝构造&#xff0c;本质上是等价的 2.获取字符串长度 int length str1.length(); // 返回字符串…

UBUNTU22.04无法安装nvidia-driver-550 依赖于 nvidia-dkms-550 (<= 550.54.15-1)

类似的报错信息&#xff0c;就是卡在了nvidia-dkms-550无法安装 Loading new nvidia-550.40.07 DKMS files… Building for 6.5.0-15-generic Building for architecture x86_64 Building initial module for 6.5.0-15-generic ERROR: Cannot create report: [Errno 17] File e…

项目启动失败,【consul】

如题&#xff0c;启动时项目未能正常启动&#xff0c;但上次都一切正常&#xff0c;日志提示&#xff1a; Consul service ids must not be empty, must start with a letter 经过排查是因为consul的consulconfigservice服务假死&#xff0c;导致无法正常获取到配置文件&am…

【全开源】JAVA人力资源招聘社会校招类型招聘系统校园招聘PC端

塑造企业高效招聘新体验 一、源码简介 招聘PC端源码&#xff0c;一款面向企业的招聘管理系统解决方案。它拥有完整的招聘流程管理功能&#xff0c;从职位发布到候选人管理&#xff0c;再到面试安排与结果反馈&#xff0c;所有环节都通过直观易用的界面进行展现&#xff0c;大…

tinyrenderer-移动镜头

同一个点的坐标在不同基坐标系中转换 设 (O, i,j,k)坐标系中点P坐标为 假设基坐标(i,j,k)与(i’,j’,k’)的转换关系为 如图&#xff0c;可以看出 其中(x’,y’,z’)为点P在基坐标(i’,j’,k’)下的坐标&#xff0c;(Ox’,Oy’,Oz’)为(i’,j’,k’)坐标系原点O’在(i,j,k…