C++--list简单实现

1.什么是list

list是C++STL容器中的一部分,list是带头双向链表,list的作用是它可以存储数据,头删尾删的时间复杂度为O(1),但不支持随机访问。list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,已让其更简单高效。

2.list的使用

list的接口众多,以下是list的一些简单接口:

构造函数( (constructor))接口说明
list (size_type n, const value_type& val = value_type())构造的list中包含n个值为val的元素
list()构造空的list
list (const list& x)拷贝构造函数
list (InputIterator first, InputIterator last)

用[first, last)区间中的元素构造list

list最重要的是迭代器的使用,由于list是链表组成的,所以list在空间中是不连续的,只能用指针去访问,不能使用[]来使用。

begin +
end
返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器
rbegin +
rend
返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的
reverse_iterator,即begin位置

3.list模拟实现

ps:要模拟实现list,必须要熟悉list的底层结构以及其接口的含义

#pragma once
#include <iostream>
#include <assert.h>
//using namespace std;
namespace sss
{template<class T>//链表节点struct List_node{List_node<T>* prev;List_node<T>* next;T value;List_node(const T& val=T()):prev(nullptr),next(nullptr),value(val){}};//迭代器template<class T,  class Ref, class Ptr>struct iterator_iterator{typedef List_node<T> Node;typedef iterator_iterator<T,Ref,Ptr> Self;//构造函数iterator_iterator(Node* node=nullptr):_node(node){;}//重载*Ref operator*(){return _node->val;}//重载->Ptr operator->(){return &_node->val;}Self& operator++(){return _node->next;}//重载++Self operator++(int){Node* tmp(*this);_node = _node->next;return tmp;}//重载--Self& operator--(){return _node->prev;}Self& operator--(int){Node* tmp(*this);_node = _node->prev;return tmp;;}bool operator!=(const Self& l){return _node != l._node;}bool operator==(const Self& l){return _node == l._node;}private:Node* _node;};template<class T>class List{typedef List_node<T>* PNode;public:typedef iterator_iterator<T,T&,T*> iterator;typedef iterator_iterator<T,const T&,const T*> const_iterator;//返回头结点iterator begin(){return _Head->next;}const_iterator begin() const{return _Head->next;}//返回尾节点iterator end(){return _Head;}const_iterator end() const{return _Head;}//初始化为空void empty_init(){_Head= new List_node<T>();_Head->prev = _Head;_Head->next = _Head;_size = 0;}//构造函数List(){empty_init();}//拷贝构造函数List(const List_node<T>& it){List(_Head);swap(it);}//赋值重载函数const List_node<T>& operator=(const List_node<T>& it){swap(it);return *this;;}//析构函数~List(){clear();delete _Head;_Head = nullptr;_size = 0;}size_t size()const{return _size;}//判空bool empty() const{return _size == 0;}T& front(){return _Head->next->value;}const T& front() const{return _Head->next->value;;}T& back(){return _Head->prev->value;}const T& back() const{return _Head->prev->value;}//尾插void push_back(const T& val) { insert(begin(), val); }//尾删void pop_back() { erase(--end()); }//头插void push_front(const T& val) { insert(begin(), val); }//头删void pop_front() { erase(begin()); }// 在pos位置前插入值为val的节点iterator insert(iterator pos, const T& val){PNode cur = pos._node;PNode newnode = new List_node<T>(val);PNode _prev = cur->prev;//前_prev->next = newnode;newnode->next = cur;//后newnode->prev = _prev;cur->prev = newnode;//大小_size++;return newnode;}// 删除pos位置的节点,返回该节点的下一个位置iterator erase(iterator pos){PNode cur = pos._node;PNode _next = cur->next;//换位置cur->next = _next;_next->prev = cur->prev;//删除delete[] cur;//大小_size--;return _next;}void clear(){assert(_size != 0);iterator it = begin();while (it!=end()){it=erase(it);++it;}}void swap(List<T>& l){std::swap(_Head, l._Head);std::swap(_size, l._size);}private:PNode _Head;size_t _size;};
}

4.list和vector的对比

vector:为动态顺序表,支持随机访问,空间利用率高,为原生指针,底层直接使用指针进行指针的加加,在插入元素时,要给所有的迭代器重新赋值,因为插入元素有可能会导致重新扩容,致使原来迭代器失效,删除时,当前迭代器需要重新赋值否则会失效。多应用于高校存储,不关心删除效率的场景。

list: 为链式存储,不支持随机访问,空间利用率不高,为原生指针的封装,在插入元素使,迭代器不会失效,但在删除元素是,迭代器需要重新赋值,否则会失效,多应用于大量插入和删除操作,不关心随机访问。


 

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

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

相关文章

vue2与vue3—引入echarts以及使用

安装echarts npm install echarts --save vue2中的引入与使用 main.js中 import { createApp } from vue import * as echarts from echarts //主要代码 import App from ./App.vue const app createApp(App) app.mount(#app) vue组件中 <div id"myChart"…

微信小程序音乐播放功能代码

咱就是话不多说直接上代码&#xff0c;不让亲戚老爷们苦等。 首先&#xff0c;在你的小程序页面的js文件中&#xff0c;定义音乐播放相关的数据和方法&#xff1a; Page({data: {isPlaying: false,audioContext: null},onLoad: function () {// 创建音频上下文this.setData({au…

Hadoop——大数据生态体系详解

一.大数据概论 1.1 大数据概念 大数据&#xff08;big data&#xff09;&#xff1a;指无法在一定时间范围内用常规软件工具进行捕捉、管理 和处理的数据集合&#xff0c;是需要新处理模式才能具有更强的决策力、洞察发现力和流程 优化能力的海量、高增长率和多样化的信息资产…

【无标题】使用html2canvas和jspdf生成的pdf在不同大小的屏幕下文字大小不一样

问题&#xff1a;使用html2canvas和jspdf生成的pdf在不同大小的屏幕下文字大小不一样&#xff0c;在mac下&#xff0c;一切正常&#xff0c;看起来很舒服&#xff0c;但是当我把页面放在扩展屏幕下&#xff08;27寸&#xff09;&#xff0c;再生成一个pdf&#xff0c;虽然排版一…

ARM Coresight 系列文章 8 - ARM Coresight 通过 APBIC 级联使用

文章目录 APBIC 回顾APBIC 级联 上篇文章&#xff1a;ARM Coresight 系列文章 7 - ARM Coresight 通过 AHB-AP 访问 异构 cpu 内部 coresight 组件 APBIC 回顾 APBIC 可以连接一个或者多个APB BUS masters&#xff0c; 例如连接一个 APB-AP 组件和带有 APB 接口的 Processor&…

js几种打印方法的几种方法

方法一&#xff1a;使用printJs库实现打印功能 1. 引入插件&#xff1a; 首先&#xff0c;在您的 HTML 文件中引入printJs库。可以通过在<head>标签中添加以下代码来引入库文件&#xff1a; <script src"https://printjs-4de6.kxcdn.com/print.min.js"&g…

【C++】STL——vector的使用、 vector增删查改函数的介绍和使用、push_back和pop_back、operator[]

文章目录 1.vector的使用2.vector的增删查改&#xff08;1&#xff09;push_back 尾插&#xff08;2&#xff09;pop_back 尾删&#xff08;3&#xff09;find 查找&#xff08;4&#xff09;insert 在position之前插入val &#xff08;5&#xff09;erase 删除指定位置的数据&…

【云原生】Kubernetes工作负载-Deployment

Deployments 一个 Deployment 为 Pod 和 ReplicaSet 提供声明式的更新能力 你负责描述 Deployment 中的目标状态&#xff0c;而 Deployment 控制器&#xff08;Controller&#xff09; 以受控速率更改实际状态&#xff0c; 使其变为期望状态。你可以定义 Deployment 以创建新…

李飞飞计算机视觉k-Nearest Neighbor

1.思路 给计算机很多数据&#xff0c;然后实现学习算法&#xff0c;让计算机学习到每个类的外形 输入&#xff1a;输入是包含N个图像的集合&#xff0c;每个图像的标签是K种分类标签中的一种。这个集合称为训练集。 学习&#xff1a;这一步的任务是使用训练集来学习每个类到底…

手搓GPT系列之 - 通过理解LSTM的反向传播过程,理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式,配超多图帮助理解(中篇)

近期因俗事缠身&#xff0c;《通过理解LSTM的反向传播过程&#xff0c;理解LSTM解决梯度消失的原理 - 逐条解释LSTM创始论文全部推导公式&#xff0c;配超多图帮助理解》的中下篇鸽了实在太久有些不好意思了。为了避免烂尾&#xff0c;还是抽时间补上&#xff08;上篇在此&…

带你用Python制作7个程序,让你感受到端午节的快乐

名字:阿玥的小东东 学习:Python、C/C++ 主页链接:阿玥的小东东的博客_CSDN博客-python&&c++高级知识,过年必备,C/C++知识讲解领域博主 目录 前言 程序1:制作粽子

Redis与其他数据库和缓存服务器的区别

名称类型数据类型查询类型附加功能Redis使用内存存储的非关系型数据库字符串、列表、集合、散列表、有序集合每种数据类型都有自己的专属命令&#xff0c;另外还有批量操作&#xff08;bulk operation&#xff09;和不完全&#xff08;partial&#xff09;的事务支持发布与订阅…

dede会员中心投稿编辑器修改成纯文字投稿方式

在我们后台发布文章的时候往往需要加入HTML或css以及php等语言的代码&#xff0c;若是单独发的话&#xff0c;没有颜色的区分&#xff0c;并且人看观看的效果也不是很好&#xff0c;所以需要实现后台能编辑语言代码的&#xff0c;之前我们处理了织梦后台的编辑器&#xff0c;现…

Spring Boot进阶(57):Spring中什么时候不要用@Autowired注入 | 超级详细,建议收藏

1. 前言&#x1f525; 注解Autowired&#xff0c;相信对于我们Java开发者而言并不陌生吧&#xff0c;在SpringBoot或SpringCloud框架中使用那是非常的广泛。但是当我们使用IDEA编辑器开发代码的时候&#xff0c;经常会发现Autowired 注解下面提示小黄线警告&#xff0c;我们把小…

【多线程】(五)工厂模式和线程池

文章目录 一、工厂模式二、线程池2.1 什么是线程池2.2 Executor 工厂类创建线程池2.3 ThreadPoolExecutor类创建线程池 三、线程池的实现 一、工厂模式 在Java中&#xff0c;工厂模式是一种创建对象的设计模式&#xff0c;它通过提供一个共同的接口来实例化对象&#xff0c;而…

Redis【实战篇】---- 分布式锁

Redis【实战篇】---- 分布式锁 1. 基本原理和实现方式对比2. Redis分布式锁的实现核心思路3. 实现分布式锁版本一4. Redis分布式锁误删情况说明5. 解决Redis分布式锁误删问题6. 分布式锁的原子性问题7. Lua脚本解决多条命令原子性问题8. 利用Java代码调试Lua脚本改造分布式锁 1…

css背景毛玻璃效果

一、结论&#xff1a;通过 css 的 backdrop-filter 属性设置滤镜函数 blur 一般会是有 背景色、透明度 的容器&#xff0c;如&#xff1a; /* 宽高等其他设置这里省略没写 */ background:rgba(3, 87, 255, 0.3); backdrop-filter: blur(10px);二、backdrop-filter 的其他用法…

Mysql教程(四):DML学习

Mysql教程&#xff08;四&#xff09;&#xff1a;DML学习 前言 DML-介绍 DML英文全称是Data Manipulation Language数据库操作语言&#xff0c;用来对数据库中表的数据记录进行增删改查。 添加数据&#xff08;INSERT&#xff09;修改数据&#xff08;UPDATE&#xff09;删除…

走访慰问空巢老人,连接传递浓浓温情

为了弘扬中华民族尊老、敬老、爱老的优良传统&#xff0c;让老人们感受到政府和社会的温暖&#xff0c;在“端午”来临之际&#xff0c;思南县青年志愿者协会联合思南县民慈社会工作服务中心、思南县小荧星幼儿园、思南县小英豪幼儿园到大河坝镇天坝村开展“走访慰问空巢老人&a…

docker 安装minIO服务器-以及数据迁移

--------------docker安装minIO-------------- 1.安装docker环境略 2.安装minIO镜像 docker pull minio/minio 3.运行MinIO docker run -p 9000:9000 -p 9090:9090 \ --name minio \ -d --restartalways \ -e "MINIO_ACCESS_KEYadmin" \ -e "MINIO_SECRET…