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

C++的List

List的使用

构造

与vector的区别

与vector的区别在于不支持 [ ]

由于链表的物理结构不连续,所以只能用迭代器访问

vector可以排序,list不能排序(因为快排的底层需要随机迭代器,而链表是双向迭代器)

(算法库里的排序不支持)(需要单独的排序)

list存在vector不支持的功能

链表的排序

vector可以用算法库里的sort排序,list不能用算法库里的sort排序排序(因为快排的底层需要随机迭代器,而链表是双向迭代器)

(算法库里的排序不支持)(需要单独的排序)

链表的排序效率要远低于算法库里的快排,因此链表的sort很少使用

即使将list拷贝会vector排序再拷贝回来,效率依旧大于直接在list中排序

升序

降序

去重(unique)

去除多个重复的数据,每个值只留一个

但是去重有一个前提,需要先排序,否则去不全

迭代器访问链表

list的剪切

将一个链表的内容转移(剪切)到另一个链表

也可以自己剪切自己,来把某个节点向前或后移动

list变为"3 1 2 4"

List的实现(双向带头循环)

链表基础结构

_head是双向带头循环链表的哨兵位(不存储有效数据)

list的迭代器

与vector不同,list在物理上是不连续的

因此不能像vector一样

因为这样++iterator不能得到下一个节点

因此可以选择建立一个类来进行封装

可以在该类中重载 " ++ " 和 " * "等运算符

是迭代器可以实现作用

但是注意不需要重载 " + "和 " - "  ,因为他们的效率很低

同时,迭代器类不需要写析构函数

因为节点不属于迭代器,只是需要用迭代器访问

节点是属于链表的

也不需要写拷贝构造(深拷贝),默认生成的浅拷贝就够了

因为没有写析构,所以也不存在析构两次的问题

->的重载

迭代器内还重载了 " -> "运算符

eg.

对于自定义类型

想要进行输出,又没有重载>>符号

方法一

比较原始的方法:

方法二

这里就是重载了 " -> "符号

从逻辑上讲

方法2应该有两个->,但是为了代码的可读性,省略了一个->

const迭代器

采用引用传参一般会给参数加const,就产生了const迭代器

但是注意

所以需要单独写一个类,让迭代器可以修改,但它指向的内容不能修改(控制返回值)

该类与之前写的迭代器的类非常相似,唯一的区别就是operator* 和operator->的返回值不同

迭代器不能修改的核心行为是operator* 和operator->

控制operator* 和operator->的返回值,从而达成不能修改的目的

但是,以上两个类重复度很高,重写一个类过于浪费

因此可以采取新添加两个模板参数

写一个类模板,传不同的模板参数,来控制返回值

这样相当于利用模板生成了两个类,交给编译器来完成

提高了开发效率

插入insert

链表里的insert不存在迭代器失效的问题,因为它不存在扩容

pos指向的位置也不会变

删除erase

erase存在迭代器失效的问题

是野指针失效

拷贝

默认的浅拷贝存在一定的问题

eg.

因为浅拷贝,指向同一块空间,会相互影响,析构两次

析构函数

这里用clear()清除数据

深拷贝

在范围for时,如果不确定遍历的类型,最好加引用&

赋值

直接交换两个链表的头节点就行

因为传入的参数不是引用,lt是lt3的临时拷贝,使用完后就会释放

交换头节点后,不仅实现了赋值,还顺便将原链表析构了

initializer_list

为了支持{ }赋值,需要写一个initializer_list

参数不用加引用&

因为initializer_list直接用{ }初始化,里面是常量数组

里面是直接用指针指向常量数组的开始和结束

模拟实现

#pragma once
#include <iostream>
using namespace std;
namespace bit
{template<class T>struct ListNode//定义一个链表节点的结构体//因为结构体内的东西全部公有,所以选择结构体,而不是类//一个类有公有私,用class,全部公有,用struct{ListNode<T>* _next;ListNode<T>* _prev;//结构体指针后加<T>模板,否则结构体指针就无法指向该类型的数据T _data;ListNode(const T& data = T())//初始化: _next(nullptr), _prev(nullptr), _data(data)//初始化列表{}};template<class T, class Ref, class Ptr>class ListIterator{typedef ListNode<T> Node;typedef ListIterator<T, Ref, Ptr> Self;Node* _node;public://++itListIterator(Node* node):_node(node){}Self& operator++()//前置{_node = _node->_next;return *this;}Self& operator--(){_node = _node->_prev;return *this;}Self operator++(int)//后置{Self tmp = *this;_node = _node->_next;return tmp;}Self operator--(int){Self tmp = *this;_node = _node->_prev;return tmp;}Ref operator*(){return _node->_data;}Ptr operator->(){return &_node->_data;}bool operator!=(const Self& it){return _node != it._node;}};//template<class T>//class ListConstIterator//{//	typedef ListNode<T> Node;//	typedef ListConstIterator<T> Self;//	Node* _node;//public://	//++it//	ListIterator(Node* node)//		:_node(node)//	{}//	Self& operator++()//前置//	{//		_node = _node->_next;//		return *this;//	}//	Self& operator--()//	{//		_node = _node->_prev;//		return *this;//	}//	Self operator++(int)//后置//	{//		Self tmp = *this;//		_node = _node->_next;//		return tmp;//	}//	Self operator--(int)//	{//		Self tmp = *this;//		_node = _node->_prev;//		return tmp;//	}//	const T& operator*()//	{//		return _node->_data;//	}//	const T* operator->()//	{//		return &_node->_data;//	}//	bool operator!=(const Self& it)//	{//		return _node != it._node;//	}//};template<class T>class list//链表{typedef ListNode<T> Node;public:typedef ListIterator<T, T&, T*> iterator;typedef ListIterator<T, const T&,const  T*> const_iterator;/*	typedef ListConstIterator<T> const_iterator;*/iterator begin(){return iterator(_head->_next);//传入匿名对象构造一个iterator类型的变量来返回}iterator end(){return iterator(_head);}void empty_init(){_head = new Node();_head->_next = _head;_head->_prev = _head;}list(){/*_head = new Node(T());_head->_next = _head;_head->_prev = _head;*/empty_init();} list(initializer_list<T> il){for (const auto& e : il){push_back(e);}}//lt2(lt1)list(const list<T>& It)//深拷贝构造{empty_init();for (const auto& e : lt){push_back(e);}}//lt1 = lt3list<T>& operator=(list<T> lt){swap(_head, lt._head);return *this;}~list(){clear();delete _head;_head = nullptr;}void clear(){auto it = begin();while (it != end()){it = erase(it);}}void push_back(const T& x){Node* newnode = new Node(x);Node* tail = _head->_prev;tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;}void insert(iterator pos, const T& x){Node* cur = pos._node;Node* newnode = new Node(x);Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;return iterator(newnode);}void erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;return iterator(next);}private:Node* _head;};void test_list1(){list<int> It1;It1.push_back(1);It1.push_back(2);It1.push_back(3);It1.push_back(4);list<int>::iterator it = It1.begin();while (it != It1.end()){*it += 10;cout << *it << " ";++it;}cout << endl;}
}

相关文章:

C++的List

List的使用 构造 与vector的区别 与vector的区别在于不支持 [ ] 由于链表的物理结构不连续,所以只能用迭代器访问 vector可以排序,list不能排序(因为快排的底层需要随机迭代器,而链表是双向迭代器) (算法库里的排序不支持)(需要单独的排序) list存在vector不支持的功能 链…...

网易有道QAnything使用CPU模式和openAI接口安装部署

网易有道QAnything可以使用本地部署大模型&#xff08;官网例子为qwen&#xff09;也可以使用大模型接口(OPENAI或者其他大模型AI接口 )的方式&#xff0c;使用在线大模型API接口好处就是不需要太高的硬件配置。 本机环境windows11 首先安装WSL环境, 安装方法参考https://zhuan…...

量子加速超级计算简介

本文转载自&#xff1a;量子加速超级计算简介(2024年 3月 13日) By Mark Wolf https://developer.nvidia.cn/zh-cn/blog/an-introduction-to-quantum-accelerated-supercomputing/ 文章目录 一、概述二、量子计算机的构建块&#xff1a;QPU 和量子位三、量子计算硬件和算法四、…...

Unity3D 基于YooAssets的资源管理详解

前言 Unity3D 是一款非常流行的游戏开发引擎&#xff0c;它提供了丰富的功能和工具来帮助开发者快速创建高质量的游戏和应用程序。其中&#xff0c;资源管理是游戏开发中非常重要的一部分&#xff0c;它涉及到如何有效地加载、管理和释放游戏中的各种资源&#xff0c;如模型、…...

Linux 自动化升级Jar程序,指定Jar程序版本进行部署脚本

文章目录 一、环境准备二、脚本1. 自动化升级Jar程序2. 指定Jar程序版本进行部署总结一、环境准备 本文在 CentOS 7.9 环境演示,以springboot为例,打包后生成文件名加上版本号,如下打包之后为strategy-api-0.3.2.jar: pom.xml<?xml version="1.0" encoding=&…...

python练习五

Title1&#xff1a;请实现一个装饰器&#xff0c;每次调用函数时&#xff0c;将函数名字以及调用此函数的时间点写入文件中 代码&#xff1a; import time time time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) # 获取当前的时间戳 # 定义一个有参装饰器来实…...

YOLOv1深入解析与实战:目标检测算法原理

参考&#xff1a; https://zhuanlan.zhihu.com/p/667046384 https://blog.csdn.net/weixin_41424926/article/details/105383064 https://arxiv.org/pdf/1506.02640 1. 算法介绍 学习目标检测算法&#xff0c;yolov1是必看内容&#xff0c;不同于生成模型&#xff0c;没有特别…...

Apache Calcite - 自定义标量函数

前言 上一篇文章中我们介绍了calcite中内置函数的使用。实际需求中会遇到一些场景标准内置函数无法满足需求&#xff0c;这时候就需要用到自定义函数。在 Apache Calcite 中添加自定义函数&#xff0c;以便在 SQL 查询中使用自定义的逻辑。这对于执行特定的数据处理或分析任务…...

STM32作业实现(四)光敏传感器

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…...

HTML+CSS 文本动画卡片

效果演示 实现了一个图片叠加文本动画效果的卡片&#xff08;Card&#xff09;布局。当鼠标悬停在卡片上时&#xff0c;卡片上的图片会变为半透明&#xff0c;同时显示隐藏在图片上的文本内容&#xff0c;并且文本内容有一个从左到右的渐显动画效果&#xff0c;伴随着一个白色渐…...

MongoDB CRUD操作: 在本地实例进行文本搜索查询

MongoDB CRUD操作&#xff1a; 在本地实例进行文本搜索查询 文章目录 MongoDB CRUD操作&#xff1a; 在本地实例进行文本搜索查询举例创建集合创建文本索引精准搜索排除短语结果排序 在本地实例运行文本搜索查询前&#xff0c;必须先在集合上建立文本索引。MongoDB提供文本索引…...

文档智能开源软件

文档智能介绍&#xff1a; 文档智能通常指的是利用人工智能技术来处理和分析文档内容&#xff0c;以实现自动化、智能化的文档管理。文档智能的应用领域非常广泛&#xff0c;包括但不限于&#xff1a; 1. **文档识别**&#xff1a;使用OCR&#xff08;光学字符识别&#xff0…...

[C][可变参数列表]详细讲解

目录 1.宏含义及使用2.宏原理分析1.原理2.宏理解 1.宏含义及使用 依赖库stdarg.hva_list 其实就是char*类型&#xff0c;方便后续按照字节进行指针移动 va_start(arg, num) 使arg指向可变参数部分(num后面) va_arg(arg, int) 先让arg指向下个元素&#xff0c;然后使用相对位置…...

54. 螺旋矩阵【rust题解】

题目 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 示例 1 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5] 示例 2 输入&#xff1a;matrix [[1,2,3,4],[5,6,…...

学习笔记——网络参考模型——TCP/IP模型(传输层)

四、TCP/IP模型-传输层 一、TCP 1、TCP定义 TCP(Transmission Control Protocol&#xff0c;传输控制协议)∶为应用程序提供可靠的面向连接的通信服务。目前&#xff0c;许多流行的应用程序都使用TCP。 连接&#xff1a;正式发送数据之前&#xff0c;提前建立好一种虚拟的&…...

Java中的Instant

在Java中&#xff0c;Instant 是 java.time 包中的一个类&#xff0c;用于表示时间轴上的一个瞬时点&#xff0c;通常以纳秒精度表示。它通常用于表示机器可读的时间戳&#xff0c;而不是人类可读的时间表示&#xff08;如日期和时间&#xff09;。 Instant 主要用于时间计算和…...

PostgreSQL的锁介绍

PostgreSQL的锁介绍 PostgreSQL 中的锁机制是一种用于控制数据并发访问的手段&#xff0c;确保数据库的完整性和一致性。在实际应用中&#xff0c;合理使用锁可以避免数据不一致和减少死锁的发生。 锁类型 PostgreSQL 提供了多种锁类型&#xff0c;以下是一些常见的锁&#…...

4分之1外螺纹怎么编程:挑战与策略解析

4分之1外螺纹怎么编程&#xff1a;挑战与策略解析 在机械制造领域&#xff0c;螺纹编程是一项至关重要的技术任务。当面对如4分之1外螺纹这样的具体需求时&#xff0c;编程人员需要综合运用专业知识与编程技巧&#xff0c;以确保螺纹的精确度和生产效率。本文将围绕四个方面、…...

运用selenium爬取京东商品数据储存到MySQL数据库中

使用Selenium爬取京东商品数据并存储到MySQL数据库中的过程可以分为几个步骤&#xff1a; 1. 准备工作 安装所需库 确保你已经安装了Python环境以及以下库&#xff1a; selenium&#xff1a;用于自动化浏览器操作。pymysql 或 mysql-connector-python&#xff1a;用于连接M…...

K8S SWCK SkyWalking全链路跟踪工具安装

官方参考&#xff1a;如何使用java探针注入器? 配置两个demo&#xff0c;建立调用关系&#xff0c; 首先创建一个基础镜像dockerfile from centos 先安装java 参考: linux rpm方式安装java JAVA_HOME/usr/java/jdk1.8.0-x64 CLASSPATH.:$JAVA_HOME/lib/tools.jar PATH…...

C++实现分布式网络通信框架RPC(3)--rpc调用端

目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中&#xff0c;我们已经大致实现了rpc服务端的各项功能代…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【算法训练营Day07】字符串part1

文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接&#xff1a;344. 反转字符串 双指针法&#xff0c;两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

大学生职业发展与就业创业指导教学评价

这里是引用 作为软工2203/2204班的学生&#xff0c;我们非常感谢您在《大学生职业发展与就业创业指导》课程中的悉心教导。这门课程对我们即将面临实习和就业的工科学生来说至关重要&#xff0c;而您认真负责的教学态度&#xff0c;让课程的每一部分都充满了实用价值。 尤其让我…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Linux 内存管理实战精讲:核心原理与面试常考点全解析

Linux 内存管理实战精讲&#xff1a;核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用&#xff0c;还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

[ACTF2020 新生赛]Include 1(php://filter伪协议)

题目 做法 启动靶机&#xff0c;点进去 点进去 查看URL&#xff0c;有 ?fileflag.php说明存在文件包含&#xff0c;原理是php://filter 协议 当它与包含函数结合时&#xff0c;php://filter流会被当作php文件执行。 用php://filter加编码&#xff0c;能让PHP把文件内容…...