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

C++基础知识7 list

list

  • 1. list的介绍及使用
    • 1.1 list的介绍
    • 1.2 list的使用
      • 1.2.1 list的构造
      • 1.2.2 list iterator的使用
      • 1.2.3 list capacity
      • 1.2.4 list element access
      • 1.2.5 list modifiers
      • 1.2.6 list的迭代器失效
    • 2.1 模拟实现list

1. list的介绍及使用

1.1 list的介绍

在这里插入图片描述

1.2 list的使用

1.2.1 list的构造

在这里插入图片描述

1.2.2 list iterator的使用

此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。

在这里插入图片描述
在这里插入图片描述

【注意】

  1. begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
  2. rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

1.2.3 list capacity

在这里插入图片描述

1.2.4 list element access

在这里插入图片描述

1.2.5 list modifiers

在这里插入图片描述

1.2.6 list的迭代器失效

前面说过,此处大家可将迭代器暂时理解成类似于指针,迭代器失效即迭代器所指向的节点的无
效,即该节点被删除了。因为list的底层结构为带头结点的双向循环链表,因此在list中进行插入
时是不会导致list的迭代器失效的,只有在删除时才会失效,并且失效的只是指向被删除节点的迭
代器,其他迭代器不会受到影响。


使用接口

#include<iostream>
#include<algorithm>
#include<list>
#include<vector>
using namespace std;

void test_list1()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;}

支持迭代器就支持范围for


struct A
{
public:A(int a1 = 1, int a2 = 1):_a1(a1), _a2(a2){cout << "A(int a1 = 1, int a2 = 1)" << endl;}A(const A& aa):_a1(aa._a1), _a2(aa._a2){cout << "A(const A& aa)" << endl;}int _a1;int _a2;
};

void test_list2()
{list<A> lt;A aa1(1, 1);lt.push_back(aa1);lt.push_back(A(2, 2));//匿名对象
}

传参走隐式类型转换


void test_list3()
{list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(6);for (auto e : lt){cout << e << " ";}cout << endl;auto it = lt.begin();int k = 3;while (k--){++it;}lt.insert(it, 30);for (auto e : lt){cout << e << " ";}cout << endl;int x = 0;cin >> x;it = find(lt.begin(), lt.end(), x);if (it != lt.end()){lt.erase(it);}for (auto e : lt){cout << e << " ";}cout << endl;
}

list迭代器只支持了+±-运算符的重载,因此实现+=智能通过++实现


void test_list4()
{list<int> lt;lt.push_back(1);lt.push_back(20);lt.push_back(3);lt.push_back(5);lt.push_back(4);lt.push_back(5);lt.push_back(6);for (auto e : lt){cout << e << " ";}cout << endl;// 升序// lt.sort();// 降序 - 仿函数// less<int> ls;// greater<int> gt;// lt.sort(gt);lt.sort(greater<int>());lt.reverse();//类方法reverse(lt.begin(), lt.end());//算法库实现的for (auto e : lt){cout << e << " ";}cout << endl;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);
}

排序时我们使用了一个仿函数,仿函数是一个类可以实现排序时升序还是降序。
merge支持将将两个排序好的链表合并插入到*this中


void test_list5()
{list<int> lt;lt.push_back(1);lt.push_back(20);lt.push_back(3);lt.push_back(5);lt.push_back(5);lt.push_back(4);lt.push_back(5);lt.push_back(6);lt.sort();for (auto e : lt){cout << e << " ";}cout << endl;lt.unique();for (auto e : lt){cout << e << " ";}cout << endl;
}

unique实现删除重复元素(在链表排序好的情况下)


void test_list6()
{// 一个链表节点转移给另一个链表std::list<int> mylist1, mylist2;std::list<int>::iterator it;// set some initial values:for (int i = 1; i <= 4; ++i)mylist1.push_back(i);      // mylist1: 1 2 3 4for (int i = 1; i <= 3; ++i)mylist2.push_back(i * 10);   // mylist2: 10 20 30it = mylist1.begin();++it;                         // points to 2mylist1.splice(it, mylist2); // mylist1: 1 10 20 30 2 3 4// mylist2 (empty)// "it" still points to 2 (the 5th element// 调整当前链表节点的顺序list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);lt.push_back(5);lt.push_back(6);for (auto e : lt){cout << e << " ";}cout << endl;int x = 0;cin >> x;it = find(lt.begin(), lt.end(), x);if (it != lt.end()){//lt.splice(lt.begin(), lt, it);lt.splice(lt.begin(), lt, it, lt.end());}for (auto e : lt){cout << e << " ";}cout << endl;
}

splice实现粘连可以是一个链表内部的粘连也可以是两个链表去粘连
在这里插入图片描述

  • 将链表x的所有结点粘连在position之前
  • 将链表x中的i结点粘连在position之前
  • 将链表x的迭代去区间粘连在position之前

void test_op()
{srand(time(0));const int N = 1000000;list<int> lt1;list<int> lt2;for (int i = 0; i < N; ++i){auto e = rand() + i;lt1.push_back(e);lt2.push_back(e);}int begin1 = clock();// 拷贝vectorvector<int> v(lt2.begin(), lt2.end());// 排序sort(v.begin(), v.end());// 拷贝回lt2lt2.assign(v.begin(), v.end());int end1 = clock();int begin2 = clock();lt1.sort();int end2 = clock();printf("list copy vector sort copy list sort:%d\n", end1 - begin1);printf("list sort:%d\n", end2 - begin2);
}

链表排序在算法库中实现,不是类方法的一部分。但是对于链表排序最好把list放到vector中排序在调用assign返回给list,在这样的代价下排序的效率也是远高于对list排序


2.1 模拟实现list

要模拟实现list,必须要熟悉list的底层结构以及其接口的含义,通过上面的学习,这些内容已基本
掌握,现在我们来模拟实现list。

#pragma once
#include<assert.h>
#include<iostream>
using namespace std;
namespace Yusei
{template<class T>struct list_node{T _date;list_node<T>* _next;list_node<T>* _prev;list_node(const T& date=T()):_next(nullptr),_prev(nullptr),_date(date){}};template<class T, class Ref, class Ptr>struct list_iterator{typedef list_node<T> Node;typedef list_iterator<T, Ref, Ptr> Self;Node* _node;list_iterator(Node* node):_node(node){}Ref operator*(){return _node->_date;}Ptr operator ->(){return &_node->_date;}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;}bool operator!=(const Self& s)const{return _node != s._node;}bool operator==(const Self& s)const{return _node == s._node;}};template<class T>class list{typedef list_node<T> Node;public:typedef list_iterator<T, T&, T*> iterator;typedef list_iterator<T, const T&, const T*> const_iterator;iterator begin(){return _head->_next;}iterator end(){return _head;}const_iterator begin() const{return _head->_next;}const_iterator end() const{return _head;}void empty_init(){_head = new Node;_head->_next = _head;_head->_prev = _head;_size = 0;}list(){empty_init();}list(initializer_list<T> il){empty_init();for (auto& e : il){push_back(e);}}list(const list<T>& lt){empty_init();for (auto& e : lt){push_back(e);}}void swap(list<T>& lt){std::swap(_head, lt._head);std::swap(_size, lt._size);}list<T>& operator=(list<T> lt){swap(lt);return *this;}~list(){clear();delete _head;_head = nullptr;}void clear(){auto it = begin();while (it != end()){it = erase(it);}}iterator insert(iterator pos, const T& x){Node* cur = pos._node;Node* prev = cur->_prev;Node* newnode = new Node(x);// prev newnode curnewnode->_next = cur;cur->_prev = newnode;newnode->_prev = prev;prev->_next = newnode;++_size;return newnode;}void push_back(const T& x){insert(end(), x);}void push_front(const T& x){insert(begin(), x);}iterator erase(iterator pos){assert(pos != end());Node* prev = pos._node->_prev;Node* next = pos._node->_next;prev->_next = next;next->_prev = prev;delete pos._node;--_size;return next;}void pop_back(){erase(--end());}void pop_front(){erase(begin());}size_t size() const{return _size;}bool empty() const{return _size == 0;}private:Node* _head;size_t _size;};struct AA{int _a1 = 1;int _a2 = 1;};template<class Container>void print_container(const Container& con){typename Container::const_iterator it = con.begin();//auto it = con.begin();while (it != con.end()){//*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : con){cout << e << " ";}cout << endl;}void test_list1(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);list<int>::iterator it = lt.begin();while (it != lt.end()){*it += 10;cout << *it << " ";++it;}cout << endl;for (auto e : lt){cout << e << " ";}cout << endl;print_container(lt);list<AA> lta;lta.push_back(AA());lta.push_back(AA());lta.push_back(AA());lta.push_back(AA());list<AA>::iterator ita = lta.begin();while (ita != lta.end()){cout << ita->_a1 << ":" << ita->_a2 << endl;cout << ita.operator->()->_a1 << ":" << ita.operator->()->_a2 << endl;++ita;}cout << endl;}void test_list2(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);// insert以后迭代器不失效list<int>::iterator it = lt.begin();lt.insert(it, 10);*it += 100;print_container(lt);// erase以后迭代器失效// 删除所有的偶数it = lt.begin();while (it != lt.end()){if (*it % 2 == 0){it = lt.erase(it);}else{++it;}}print_container(lt);}void test_list3(){list<int> lt1;lt1.push_back(1);lt1.push_back(2);lt1.push_back(3);lt1.push_back(4);list<int> lt2(lt1);print_container(lt1);print_container(lt2);list<int> lt3;lt3.push_back(10);lt3.push_back(20);lt3.push_back(30);lt3.push_back(40);lt1 = lt3;print_container(lt1);print_container(lt3);}void func(const list<int>& lt){print_container(lt);}void test_list4(){// 直接构造list<int> lt0({ 1,2,3,4,5,6 });// 隐式类型转换list<int> lt1 = { 1,2,3,4,5,6,7,8 };const list<int>& lt3 = { 1,2,3,4,5,6,7,8 };func(lt0);func({ 1,2,3,4,5,6 });print_container(lt1);//auto il = { 10, 20, 30 };初始化列表/*	initializer_list<int> il = { 10, 20, 30 };cout << typeid(il).name() << endl;cout << sizeof(il) << endl;*/}
}

相关文章:

C++基础知识7 list

list 1. list的介绍及使用1.1 list的介绍1.2 list的使用1.2.1 list的构造1.2.2 list iterator的使用1.2.3 list capacity1.2.4 list element access1.2.5 list modifiers1.2.6 list的迭代器失效 2.1 模拟实现list 1. list的介绍及使用 1.1 list的介绍 1.2 list的使用 1.2.1 l…...

Android 车联网——汽车模块介绍(附1)

汽车模块指的是车辆中独立的电子控制单元(ECUs),如发动机控制单元(ECU)、车身控制模块(BCM)等,它们负责特定的功能或系统。 一、控制类模块 这些模块主要用于控制车辆的不同系统,确保车辆各部分的正常运行。 1、ECM ECM(Electronic Control Module,电子控制模块)…...

Windows下SDL2创建最简单的一个窗口

先看运行效果 再上代码&#xff1a; #include <stdio.h> #include "SDL.h"int main(int argc, char* argv[]) {// 初始化SDL视频子系统if (SDL_Init(SDL_INIT_VIDEO) -1){printf("Error: %s\n", SDL_GetError());return -1;} // 创建一个窗口SDL_…...

C++ | Leetcode C++题解之第406题根据身高重建队列

题目&#xff1a; 题解&#xff1a; class Solution { public:vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {sort(people.begin(), people.end(), [](const vector<int>& u, const vector<int>& v) …...

【网络安全】-ssrf服务器请求伪造攻击-burp

SSRF攻击服务器请求伪造攻击 CSRF攻击跨站请求伪造攻击也称客户端请求伪造攻击 两种攻击最主要的区别是一个在服务器&#xff0c;一个在客户端。 文章目录 前言 什么是SSRF攻击? 1.分类&#xff1a; 针对服务器的 SSRF 攻击&#xff1a; 针对后端系统的SSRF攻击&#xff1a; …...

C语言 | Leetcode C语言题解之第405题数字转换为十六进制数

题目&#xff1a; 题解&#xff1a; char * toHex(int num){int i0;char *nums(char*)malloc(sizeof(char)*32);unsigned int newnum(unsigned int)num;if(num0){nums[0]0;nums[1]\0;return nums;}while(newnum>1){int flagnewnum%16;newnum/16;if(flag<9){nums[i]flag0…...

Python快速入门 —— 第一节:基础类型

Python 快速教程说明 适用人群 有其他语言编程基础&#xff0c;或了解过python的群体&#xff0c;至少需要知道变量、对象、函数等基本概念想快速通过python实现一些功能&#xff0c;却不想了解python的底层实现的人群想快速了解python语言框架的人群有兴趣了解python的任何人…...

评价类——熵权法(Entropy Weight Method, EWM),完全客观评价

目录 一、 熵权法赋权代码说明1.1 介绍 二、 手把手教你运行代码2.1 数据示例2.2 可直接运行代码2.3 shangquanfa_eg_Sheet1.csv数据可视化2.4 代码运行过程截屏2.5 代码运行结果截屏2.6 对熵权法的结果分析 三、 提供的代码如何修改&#xff1f;四、 为什么确定极小化指标&…...

Redis——通用命令

目录 Redis通用命令Redis中最核心的两个命令getset Redis全局命令keys语法注意事项 existsdel(delete)expirettlredis的key的过期策略是怎么实现的&#xff1f;了解拓展 type总结 Redis通用命令 Redis的命令非常非常多&#xff0c;所以 1. 掌握常用命令&#xff08;多操作练习…...

(k8s)kubernetes 挂载 minio csi 的方式(pod挂载pvc存在csi驱动问题,挂载不上)

一、安装Minio&#xff08;Minio分布式集群搭建部署_minio集群最少几台-CSDN博客&#xff09; 生成accessKeyID和secretAccessKey&#xff1a; 二、安装csi-s3插件(在k8s集群上) 首先我们把插件的yaml文件都下载下来&#xff0c;为了保证版本测试的一致性&#xff0c;我们下载…...

python tkinter

基本使用 基于tkinter创建 GUI基本四步&#xff1a;窗口->组件->布局->事件 1.创建窗口对象 from tkinter import *root Tk() # 创建窗口root.mainloop() # 进入事件循环 2.创建组件 按钮文本等组件 btn Button(root) # 创建Button组件&#xff0c;使组件在…...

Flink CEP(复杂事件处理)高级进阶

Flink CEP(Complex Event Processing,复杂事件处理)是 Apache Flink 中用于复杂事件模式检测的库。它允许用户定义复杂的事件模式,从流数据中检测出符合模式的事件序列。这在实时监控、欺诈检测、用户行为分析等场景中非常有用。 Flink CEP 高级进阶 为了深入理解和使用 …...

libmodbus:写一个modbusTCP服务

初级代码游戏的专栏介绍与文章目录-CSDN博客 我的github&#xff1a;codetoys&#xff0c;所有代码都将会位于ctfc库中。已经放入库中我会指出在库中的位置。 这些代码大部分以Linux为目标但部分代码是纯C的&#xff0c;可以在任何平台上使用。 源码指引&#xff1a;github源…...

函数模板(初阶)

Hello&#xff0c;大家好&#xff0c;我们大家都知道&#xff0c;C这个编程语言是由C语言继承而来的&#xff0c;因为是继承&#xff0c;所以我们的C就要做出一些区分&#xff0c;要不然的话&#xff0c;就和C语言没有本质上的区别了&#xff0c;我们现在在社会中使用比较多的是…...

中间件之RocketMQ

RocketMQ是一个开源的分布式消息队列系统&#xff0c;起源于阿里巴巴集团内部。最初&#xff0c;RocketMQ&#xff08;前身为Metaq&#xff09;被设计为满足阿里巴巴集团内部大规模分布式系统下的高吞吐量、低延迟和高可靠性的消息传递需求。随着其在阿里巴巴内部的广泛应用和不…...

linux第二课(docker的安装使用)

目录 一.关于docker (1)背景引入 (2)docker介绍 (3)功能 (4)Docker架构 二.docker的安装及相关的命令 (1)docker的安装 (2)docker的配置 (3)docker镜像命令 (4)容器命令 三.docker安装myaql ​编辑 四.数据卷挂载 1.数据卷挂载引入 2.数据卷挂载图解 3.数据卷的安装…...

Java数据存储结构——二叉查找树

文章目录 22.1.2二叉查找树22.1.2.1 概述22.1.2.1二叉查找树添加节点22.1.2.2二叉查找树查找节点22.1.2.3 二叉树遍历22.1.2.4 二叉查找树的弊端 22.1.2二叉查找树 22.1.2.1 概述 二叉查找树,又称二叉排序树或者二叉搜索树 二叉查找树的特点&#xff1a; 每一个节点上最多有…...

JavaScript 事件处理

一、简介 ​ 事件&#xff1a;发生在HTML元素上的事情&#xff0c;可以是用户的行为&#xff0c;也可以是浏览器的行为&#xff0c;如 用户点击了某个HTML元素用户将鼠标移动到某个HTML元素上用户输入数据时光标离开页面加载完成 ​ 事件源&#xff1a;事件触发的源头&#xf…...

容器技术--Docker应用部署

应用部署 容器部署mysql 搜索并拉取镜像;基于镜像启动容器,注意端口映射、目录映射启动后即可连接# 搜索镜像 docker search mysql # 拉取镜像 docker pull mysql:5.7 # docker pull mysql 默认拉取最新的# 创建mysql容器, -p端口映射(宿主端口:容器端口) -e 环境变量,镜…...

医院管理|基于java的医院管理系统小程序(源码+数据库+文档)

医院管理系统小程序 目录 基于java的医院管理系统小程序 一、前言 二、系统设计 三、系统功能设计 医生信息管理 排班信息管理 科室信息管理 科室预约 病历信息 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取&#xff1a;…...

设计模式和设计原则回顾

设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频

使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...

关于iview组件中使用 table , 绑定序号分页后序号从1开始的解决方案

问题描述&#xff1a;iview使用table 中type: "index",分页之后 &#xff0c;索引还是从1开始&#xff0c;试过绑定后台返回数据的id, 这种方法可行&#xff0c;就是后台返回数据的每个页面id都不完全是按照从1开始的升序&#xff0c;因此百度了下&#xff0c;找到了…...

Python实现prophet 理论及参数优化

文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候&#xff0c;写过一篇简单实现&#xff0c;后期随着对该模型的深入研究&#xff0c;本次记录涉及到prophet 的公式以及参数调优&#xff0c;从公式可以更直观…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Git 3天2K星标:Datawhale 的 Happy-LLM 项目介绍(附教程)

引言 在人工智能飞速发展的今天&#xff0c;大语言模型&#xff08;Large Language Models, LLMs&#xff09;已成为技术领域的焦点。从智能写作到代码生成&#xff0c;LLM 的应用场景不断扩展&#xff0c;深刻改变了我们的工作和生活方式。然而&#xff0c;理解这些模型的内部…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...