List

在这里插入图片描述

欢迎来到Cefler的博客😁
🕌博客主页:那个传说中的man的主页
🏠个人专栏:题目解析
🌎推荐文章:题目大解析2

在这里插入图片描述


目录

  • 👉🏻List概念
  • 👉🏻List constructor
  • 👉🏻Iterators
  • 👉🏻Capacity
  • 👉🏻Element access
  • 👉🏻Modifiers
  • 👉🏻Operations
    • sort
    • merge
    • unique
    • remove
    • splice
  • 👉🏻list的模拟实现
    • list_node(链表结点)
    • 封装迭代器
    • insert
    • erase
    • push_back
    • 头插/删,尾插/删
    • empty_init函数
    • 无参构造函数
    • swap函数、clear函数、拷贝构造函数、析构函数
    • 迭代器的begin和end() 【非const】
    • 🌛插入自定义类型,编译器优化书写格式->

👉🏻List概念

C++中的list是一种双向链表数据结构。它可以存储任意类型的元素,并且可以在常数时间内在任意位置插入或删除元素。list提供了许多操作,如在开头或结尾插入/删除元素,访问元素,以及在列表中搜索元素。与向量(vector)相比,list的插入和删除操作更高效,但是访问元素的效率较低。

👉🏻List constructor

在这里插入图片描述

和vector差不多,list的构造函数中,有:

  • 无参默认构造
  • n个val值构造
  • 模板函数,迭代器区间初始化构造
  • 拷贝构造

List官方文档

👉🏻Iterators

在这里插入图片描述

👉🏻Capacity

在这里插入图片描述

👉🏻Element access

在这里插入图片描述

👉🏻Modifiers

在这里插入图片描述

👉🏻Operations

在这里插入图片描述

sort

可能有人会问,std中不是有提供一个全局的sort函数,为什么list内部还要再支持一个sort接口?
我们看下原因
![在这里插入图片描述](https://img-blog.csdnimg.cn/dedb61f888414ef5ae9c4c02703b861d.pn
在这里插入图片描述
噢,原来是因为list的迭代器是双向迭代器,而std的sort只接收随机迭代器类型,因为双向迭代器不支持+/-功能,所以list用不了std的sort,只能自己造轮子了。
在这里插入图片描述
list的sort默认情况下是升序,list的排序有:

  • 升序:< less
  • 降序:> greater
	list<int> l;for (int i = 1; i <= 4; i++){l.push_back(i);}//我们想要个降序greater<int> gt;//	list<int> l;for (int i = 1; i <= 4; i++){l.push_back(i);}//我们想要个降序greater<int> gt;//l.sort(greater<int> ());匿名对象也可以l.sort(gt);

list的sort底层是实现是用归并排序

std的sort底层实现是快速排序,要比list的排序快,所以有时候,如果数据量比较少一般直接用list的排序,
但如果数据量大的话,我们可以先将list里面的数据拷贝到vector上,然后借助vector用std的排序进行快排,排序完之后,用assign的迭代器区间再拷贝回list中,这样就可以偷梁换柱了。

#include <iostream>
#include <vector>
#include <list>
#include <algorithm> //使用sort排序记得包含头文件
using namespace std;
void Test1()
{list<int> l;for (int i = 10; i >=0; i--){l.push_back(i);}vector<int> v(l.begin(), l.end());//拷贝进vectorsort(v.begin(), v.end());l.assign(v.begin(), v.end());//再拷贝回去list<int>::iterator it = l.begin();while (it != l.end()){cout << *it << " ";it++;}
}

merge

在这里插入图片描述

合并两个链表,但是前提是这两个链表是有序的。

// list::merge
#include <iostream>
#include <list>// compare only integral part:
bool mycomparison (double first, double second)
{ return ( int(first)<int(second) ); }int main ()
{std::list<double> first, second;first.push_back (3.1);first.push_back (2.2);first.push_back (2.9);second.push_back (3.7);second.push_back (7.1);second.push_back (1.4);first.sort();second.sort();first.merge(second);// (second is now empty)second.push_back (2.1);first.merge(second,mycomparison);std::cout << "first contains:";for (std::list<double>::iterator it=first.begin(); it!=first.end(); ++it)std::cout << ' ' << *it;std::cout << '\n';return 0;
}

输出:
first contains: 1.4 2.2 2.9 2.1 3.1 3.7 7.1

请注意,在第二次合并中,函数 mycompare(仅比较整数部分)没有考虑 2.1 低于 2.2 或 2.9,因此它入到它们之后,在 3.1 之前

unique

unique 函数的作用是将容器中相邻的重复元素保留一个,并删除其余的重复元素。具体而言,它会遍历容器中的元素,将相邻的重复元素中的后一个元素删除。
以下是 std::list 的 unique 函数的用法示例:

#include <iostream>
#include <list>int main() {std::list<int> myList = {1, 2, 2, 3, 3, 3, 4, 5, 5};myList.unique();for (const auto& element : myList) {std::cout << element << " ";}return 0;
}

输出结果为:1 2 3 4 5。

注意,unique 函数只能去除相邻的重复元素,如果容器中存在非相邻的重复元素,它们不会被去除。如果需要去除所有重复元素,可以先使用 std::sort 函数对容器进行排序,然后再使用 unique 函数

remove

remove 函数用于删除容器中指定的元素。
remove 函数的工作原理是遍历容器,找到所有与指定值相等的元素,并将它们从容器中删除。
remove 函数的语法如下:

void remove(const T& value);

splice

splice 是 std::list 类提供的一个成员函数,用于将另一个 std::list 的元素插入到当前 std::list 中的指定位置。
splice 函数的语法如下:👇🏻

void splice (iterator position, list& x);
void splice (iterator position, list& x, iterator i);
void splice (iterator position, list& x, iterator first, iterator last);
  • 第一个版本将 x 中的所有元素插入到当前 list 的 position 之前。
  • 第二个版本将 x 中第i个元素开始之后的元素插入到当前 list 的 position 之前。
  • 第三个版本将 x 中的 [first, last) 范围内的元素插入到当前 list 的 position 之前。

注意,splice 操作会改变被插入的 list,并且被插入的元素会从原来的 list 中移除。
以下是一个示例代码,演示了如何使用 splice 函数:👇🏻

#include <iostream>
#include <list>int main() {std::list<int> list1 = {1, 2, 3};std::list<int> list2 = {4, 5, 6};auto it = list1.begin();std::advance(it, 2); // 将迭代器移动到第三个元素的位置list1.splice(it, list2); // 将 list2 中的所有元素插入到 list1 的第三个元素之前// 输出 list1 的元素for (const auto& num : list1) {std::cout << num << " ";}std::cout << std::endl;// 输出 list2 的元素for (const auto& num : list2) {std::cout << num << " ";}std::cout << std::endl;return 0;
}

输出结果为:
1 2 4 5 6 3

👉🏻list的模拟实现

list_node(链表结点)

template <class T>//模板结构体,为了存储可能不同的数据类型struct list_node   //这边用strcut主要是想开放所有的成员变量,所以不用class{T _data;list_node<T>* _next;list_node<T>* _prev;list_node(const T& val = T()):_data(val), _next(nullptr), _prev(nullptr){}};

封装迭代器

template <class T>struct __list_iterator//封装一个迭代器,实现迭代器的++/--等等功能,解引用//迭代器牛逼之处//封装屏蔽底层差异和实现细节//提供统一的访问修改方式{typedef list_node<T>   Node;typedef __list_iterator<T>  self;Node* _node;__list_iterator(Node* node)//传参进来:_node(node){}self& operator++(){_node = _node->_next;return *this;}self operator++(int)//后置++{self tmp(*this);_node = _node->_next;return tmp;}self& operator--(){_node = _node->_prev;return *this;}self operator--(int)//后置--{self tmp(*this);_node = _node->_prev;return tmp;}T& operator*(){return _node->_data;}T* operator->() //指针访问结构体{return &(_node->_data);}bool operator!=(const self& s){return _node != s._node;}bool operator==(const self& s){return _node == s._node;}};

insert

iterator insert(iterator pos, const T& x){Node* newnode = new Node(x);//先开辟新空间Node* cur = pos._node;Node* prev = cur->_prev;prev->_next = newnode;newnode->_prev = prev;newnode->_next = cur;cur->_prev = newnode;//insert后pos仍指向原空间,迭代器没失效++_size;return iterator(newnode);}

erase

iterator erase(iterator pos){Node* cur = pos._node;Node* prev = cur->_prev;//上一个结点Node* next = cur->_prev;//下一个结点prev->_next = next;next->_prev = prev;delete cur;//delete之后,cur即pos指向的空间已经不是原空间了,迭代器妥妥失效了!//所以需要返回删除位置的下一位置--_size;return iterator(next);}

push_back

void push_back(const T& x){//先建新空间Node* tail = _head->_prev;Node* newnode = new Node(x);tail->_next = newnode;newnode->_prev = tail;newnode->_next = _head;_head->_prev = newnode;}

insert进行尾插

void push_back(const T& x){insert(end(), x);}

头插/删,尾插/删

           void push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}void pop_back(){erase(--end());}void pop_front(){erase(begin());}

empty_init函数

void empty_init(){_head = new Node;_head->_next  = _head;_head->_prev = _head;_size = 0;}

无参构造函数

void empty_init(){_head = new Node;_head->_next  = _head;_head->_prev = _head;}list(){empty_init();}

swap函数、clear函数、拷贝构造函数、析构函数

void swap(list<T>& lt){std::swap(this->_head, lt._head);std::swap(this->_size, lt._size);}void clear(){_head->_next = _head;_head->_prev = _head;}/*	void clear()  //全部清除版本{iterator it = begin();while (it != end()){it = erase(it);}}*/
list( list<T>& lt)//拷贝构造{empty_init();for (auto e : lt){push_back(e);}}~list(){//clear();delete _head;_head = nullptr;}

迭代器的begin和end() 【非const】

typedef __list_iterator<T>  iterator;iterator begin()  //返回值会将_head->_next的值拷入进行构造{//return (iterator)_head;这边无需强转return _head->_next;}iterator end(){return _head;}

🌛插入自定义类型,编译器优化书写格式->

struct AA{AA(int a1 = 0, int a2 = 0):_a1(a1), _a2(a2){}int _a1;int _a2;};void test_list3(){list<AA> lt;lt.push_back(AA(1, 1));lt.push_back(AA(2, 2));lt.push_back(AA(3, 3));list<AA>::iterator it = lt.begin();while (it != lt.end()){//cout << (*it)._a1<<" "<<(*it)._a2 << endl;cout << it->_a1 << " " << it->_a2 << endl;cout << it.operator->()->_a1 << " " << it.operator->()->_a1 << endl;++it;}cout << endl;/*	int* p = new int;*p = 1;AA* ptr = new AA;ptr->_a1 = 1;*/}

在这里插入图片描述

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

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

相关文章

vue项目预览pdf功能(解决动态文字无法显示的问题)

最近&#xff0c;因为公司项目需要预览pdf的功能&#xff0c;开始的时候找了市面上的一些pdf插件&#xff0c;都能用&#xff0c;但是&#xff0c;后面因为pdf变成了需要根据内容进行变化的&#xff0c;然后&#xff0c;就出现了需要动态生成的文字不显示了。换了好多好多的插件…

Java:ArrayList集合、LinkedList(链表)集合的底层原理及应用场景

ArrayList集合的底层原理及应用场景 LinkedList&#xff08;链表&#xff09;集合的底层原理及应用场景 单向链表 增加数据 删除数据 双向链表 LinkedList的应用场景之一:可以用来设计队列 入队 出队 LinkedList的应用场景之一:可以用来设计栈 压栈&#xff08;push),addFirst…

AWS security 培训笔记

云计算的好处 Amazon S3 (Storage) Amazon EC2 (Compute) 上图aws 的几个支柱&#xff1a;安全是其中一个啦 其中安全有几个方面 IAMdetection基础架构保护数据保护应急响应 关于云供应商的责任 data center 原来长这样 &#xff0c;据说非常之隐蔽的 如果有天退役了&#xf…

SpringBoot + Vue 微人事(十)

职位管理前后端接口对接 先把table中的数据展示出来&#xff0c;table里面的数据实际上是positions里面的数据&#xff0c;就是要给positions:[] 赋上值 可以在methods中定义一个initPosition方法 methods:{//定义一个初始化positions的方法initPositions(){//发送一个get请求…

【学习FreeRTOS】第12章——FreeRTOS时间管理

1.FreeRTOS系统时钟节拍 FreeRTOS的系统时钟节拍计数器是全局变量xTickCount&#xff0c;一般来源于系统的SysTick。在STM32F1中&#xff0c;SysTick的时钟源是72MHz/89MHz&#xff0c;如下代码&#xff0c;RELOAD 9MHz/1000-1 8999&#xff0c;所以时钟节拍是1ms。 portNV…

《TCP IP网络编程》第十八章

第 18 章 多线程服务器端的实现 18.1 理解线程的概念 线程背景&#xff1a; 第 10 章介绍了多进程服务端的实现方法。多进程模型与 select 和 epoll 相比的确有自身的优点&#xff0c;但同时也有问题。如前所述&#xff0c;创建&#xff08;复制&#xff09;进程的工作本身会…

蔚来李斌卖手机:安卓系统,苹果售价,一年一发

‍作者 | Amy 编辑 | 德新 车圈大佬的玩法真让人寻不着套路&#xff01; 苹果的库克和小米的雷布斯&#xff0c;甚至是FF贾老板准备许久&#xff0c;都想分一块新能源车的蛋糕&#xff0c;蔚来李斌却反手进军手机界&#xff0c;从宣布造手机到手机入网仅仅隔了一年。 近期&a…

阿里云使用WordPress搭建个人博客

手把手教你使用阿里云服务器搭建个人博客 一、免费创建服务器实例 1.1 点击试用 点击试用会需要你创建服务器实例&#xff0c;直接选择默认的操作系统即可&#xff0c;点击下一步 1.2 修改服务器账号密码 二、创建云数据库实例 2.1 免费获取云数据库使用 2.2 实例列表页 在…

Three.js 实现模型材质局部辉光效果和解决辉光影响场景背景图显示的问题

1.Three.js 实现模型材质局部辉光效果 2.解决辉光效果影响场景背景图显示的问题 相关API的使用&#xff1a; 1. EffectComposer&#xff08;渲染后处理的通用框架&#xff0c;用于将多个渲染通道&#xff08;pass&#xff09;组合在一起创建特定的视觉效果&#xff09; 2. …

变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践

目录导读 变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践1. 什么是变更通知2. 变更通知的场景分析3. 变更通知的技术方案3.1 变更通知的技术实现方案 4. 变更通知的最佳实践总结5. 参考资料 变更通知在开源SpringBoot/SpringCloud微服务中的最佳实践 1. 什么是变更通…

阿里云席明贤:明天的视频云2.0

编者按 本文是“解构多媒体新常态”系列文章的第二篇&#xff0c;LiveVideoStack对话了阿里云视频云负责人席明贤&#xff08;花名右贤&#xff09;。面对风云变幻的内外环境&#xff0c;阿里云在视频云赛道是坚定向前的&#xff0c;在与右贤的接触中&#xff0c;他给我留下非常…

RabbitMQ快速入门

RabbitMQ快速入门 1、Part1前言 Rabbitmq 是使用 Erlang 语言开发的开源消息队列系统&#xff0c;基于 AMQP 实现&#xff0c;是一种应用程序对应用程序的通信方 法&#xff0c;应用程序通过读写出入队列的消息来通信&#xff0c;而无需专用连接来链接它们。消息传递指的是应…

优酷视频码率、爱奇艺视频码率、B站视频码率、抖音视频码率对比

优酷视频码率、爱奇艺视频码率与YouTube视频码率对比 优酷视频码率&#xff1a; 优酷的视频码率可以根据视频质量、分辨率和内容类型而变化。一般而言&#xff0c;优酷提供了不同的码率选项&#xff0c;包括较低的标清&#xff08;SD&#xff09;码率和较高的高清&#xff08;…

Redis高可用:主从复制详解

目录 1.什么是主从复制&#xff1f; 2.优势 3.主从复制的原理 4.全量复制和增量复制 4.1 全量复制 4.2 增量复制 5.相关问题总结 5.1 当主服务器不进行持久化时复制的安全性 5.2 为什么主从全量复制使用RDB而不使用AOF&#xff1f; 5.3 为什么还有无磁盘复制模式&#xff…

信创办公–基于WPS的EXCEL最佳实践系列 (公式和函数)

信创办公–基于WPS的EXCEL最佳实践系列 &#xff08;公式和函数&#xff09; 目录 应用背景相关知识操作步骤1、认识基本的初级函数2、相对引用&#xff0c;绝对引用&#xff0c;混合引用3、统计函数4、文本函数 应用背景 熟练掌握Excel的函数工具能让我们在日常的使用中更加方…

RGOS日常管理操作

RGOS日常管理操作 一、前言二、RGOS平台概述2.1、锐捷设备的常用登陆方式2.2、使用Console登入2.3、Telnet远程管理2.4、SSH远程管理2.5、登陆软件&#xff1a;SecureCRT 三、CLI命令行操作3.1、CLI命令行基础3.2、CLI模式3.3、CLI模式互换3.4、命令行特性3.4.1、分屏显示3.4.2…

设计模式-观察者模式(观察者模式的需求衍变过程详解,关于监听的理解)

目录 前言概念你有过这样的问题吗&#xff1f; 详细介绍原理&#xff1a;应用场景&#xff1a; 实现方式&#xff1a;类图代码 问题回答监听&#xff0c;为什么叫监听&#xff0c;具体代码是哪观察者模式的需求衍变过程观察者是为什么是行为型 总结&#xff1a; 前言 在软件设计…

Windows下问题定位

1、内存相关知识点&#xff1b; 1&#xff09;windows下32位进程&#xff0c;用户态为2G内存&#xff0c;内核态也为2G内存&#xff1b;却别于linux操作系统&#xff1b; 备注&#xff1a;可以通过命令行与管理员权限&#xff0c;启动3G的用户态空间&#xff0c;但是部…

python 使用 pdf2image 库将PDF转换为图片

在 Ubuntu 上实现网络穿透&#xff1a;手把手教你搭建FRPS服务器 初环境步骤一&#xff1a;安装pdf2image库步骤二&#xff1a;导入必要的库步骤三&#xff1a;指定PDF文件路径步骤四&#xff1a;将PDF转换为图片步骤五&#xff1a;保存图像为图片文件完整代码运行结果 在数字化…

Open cv C++安装

注意;要退出conda的虚拟环境 依赖 1.更新系统 sudo apt-get update sudo apt-get upgrade 2.安装相关的依赖 sudo apt-get install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev sudo apt-get install libjpeg-de…