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

list下

文章目录

      • 注意:
      • const迭代器
        • 怎么写?
        • 运用场合?
      • insert
      • erase
      • 析构函数
      • 赋值和拷贝构造
        • 区别?
        • 拷贝构造不能写那个swap,为什么?
        • 拷贝构造代码
      • 面试问题
        • 什么是迭代器失效?
        • vector、list的区别?
      • 完整代码

注意:

delete 和delete[]之间不能用错
delete是单个;
delete是一个数组;
vector、string都是delete[];
list本质不是数组是列表,所以delete

const迭代器

怎么写?
		typedef __list_iterator<T, T&, T*> iterator; // 放public里面不然外面动不了T,就是用不了模板,私有的不能用typedef __list_iterator<T,const T&,const T*> const_iterator;//const迭代器//迭代器用节点的指针就行了iterator begin(){return iterator(_head->_next);//注意这里返回的是迭代器,不是_head头部指针、这个是list类里面的成员变量//现在是把头部指针_head传过去,然后迭代器调用他的拷贝函数;//这里面就是构造函数、因为传过去的是Node类型;}iterator end(){return iterator(_head);}//const_iteratorconst_iterator begin() const{return const_iterator(_head->_next); }const_iterator end() const{return const_iterator(_head);}

image.png
模板里面放多个参数,在传模板时候,如上图,右边框起来上面是普通的迭代器,下面有const,用哪种就会自动传过去,同时Self也是对应的迭代器;
image.png

运用场合?

一般const指针是不用的;
什么情况下去用?
传参给另一个函数用的时候会用到;
例如下面功能是打印的成员函数

	void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;}

insert

在pos位置插入,这个pos是一个迭代器,插入后这个节点以及前后节点的_next和_prev要注意怎么赋值;
cur是pos指向的当前节点;
newnode是新插入的节点;
image.png

		//insert//现在要的是列表里面的那两个指针next\prev;//迭代器里面就有_node存的是Node*类型;void insert(iterator pos,const T& x = T()){Node* cur = pos._node;//pos是迭代器所以调用他的成员函数用点符号"."虽然类似指针但是不能->,这个是指针用的Node* prev = cur->_prev;Node* newnode = new Node(x);newnode->_next = cur;newnode->_prev = prev;cur->_prev = newnode;prev->_next = newnode;}

写完insert,push_back和push_front就可以直接用insert的

		//头插void push_front(const T& x = T()){insert(begin(), x);}//尾插void push_back(const T& x = T()){//Node* tail = _head->_prev;//Node* newnode = new Node(x);//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;//再pos是end()的时候插入,end()表示最后一个元素的后一个位置,所以插入这个位置就是尾插insert(end(), x);}

erase

头节点指向的迭代器就是end();
end()的意思是最后一个元素的后一个位置,那就是_head,这个头节点;
和insert类似,_next/_prev都要重新赋值一下:
image.png

		//erase,erase是要返回删除的位置的后一个位置的Node* erase(iterator pos){//cur里面存现在的地址//prev是cur上一个地址assert(pos  != end()); //头节点不能删Node* cur = pos._node;  Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;//delete[]必须是数组,所以要注意return next;}

头删除、和尾删除就可以用erase了

		//尾删void pop_back(){//erase(iterator(_head->_prev));erase(--end());}//头删除void pop_front(){erase(begin());}

析构函数

析构,栈里面的是先定义的后出去,现进后出;
析构是释放了还要置空;

		void clear(){Node* cur = _head->_next;while (cur != _head){_head->_next = cur->_next;delete cur;cur = _head->_next}_head = head->next = head->prev;//重新关联起来,双向带头循环列表;}//析构~list(){clear();detete _head;_head = nullptr;}

clear的作用是清空这个链表里面的内容,_head这个头节点是没有data的,所以是不用动的;
析构是直接这个链表对象空间释放了,所以_head也要释放;

赋值和拷贝构造

区别?

问:string为什么这边写了要先置位nullptr,然而这边的list没有呢?
答:
拷贝构造l1(l2),l1首先要初始化、至少里面是个nullptr,因为他还没有被创建出来;
赋值的话l1 = l2,首先你这个l1是不是已经是先定义出来的,所以不用初始化的;
image.png

拷贝构造不能写那个swap,为什么?

答:这样的话在传参数时就是又一个拷贝构造,那就会无限循环

拷贝构造代码
		//拷贝函数l1(l2)//首先l1是没有创建出来的,所以要初始化list(const list<T>& lt){//先初始化,list里面成员函数是什么?_head,_head里面的内容Node* _head;_head->_next = _head->_prev = _head;//往里面插入后面的值就行了//方法一/*const_iterator it = lt.begin();while (it != it.end()){push_back(*it);//运算符重载过*it了,传过去的是_node->_datait++;}*///方法二for (auto e : lt)//本质调用的迭代器{push_back(e);}}

在string和vector里面是这样的,for循环本质使用的是迭代器,有迭代器就有for循环,e理论上就是*it
image.png

面试问题

什么是迭代器失效?

迭代器失效具体内容

vector、list的区别?

vector是一个动态增长的数据
优点:支持随机访问operator[],排序、二分查找、堆算法等等可用到;
缺点:空间不够要增容、头部或者中间插入效率低o(n);

list是一个带头双向循环的链表
优点:任意位置插入效率高o(1);
缺点:不支持随机访问;

总结:list和vector相辅相成、是两个互补的容器

完整代码

test.c
在这里插入图片描述

#pragma once
namespace list_test
{template<class T>//struct__list_node,两个_这种取名方式一般表示一会这个会在别的里面用,在这里就表示,list类里面直接用的类外面定义的struct __list_code这个结构体struct __list_node{__list_node<T>* _next; // 别忘了这里要写<T>__list_node<T>* _prev;T _data;//列表需要构造函数来初始化__list_node(const T& x = T())//这个T(),指的是没有传值过来那就直接为0:_data(x),_next(nullptr)  ,_prev(nullptr){}};//struct迭代器__list_iteratortemplate<class T, class Ref, class Ptr>//这个就是三个模板参数struct __list_iterator{typedef __list_node<T> Node;typedef __list_iterator<T, Ref, Ptr> Self;Node* _node;//构造函数,struct怎么写构造函数、就是看这个里面成员函数有哪些__list_iterator(Node* node):_node(node){}//构造传的是里面的成员函数、拷贝是传的类或者说这个结构体//浅拷贝,这个是默认函数、不用写的__list_iterator(const Self& it) {_node = it._node;}// operator*,读_node中的data,data的类型是T,所以函数返回值类型是TRef operator*(){return _node->_data;}//++Self& operator++(){_node = _node->_next;return *this;}//后置++Self operator++(int) //后置++里面就放个int,这是设计出来的伪参数,用来区分前后置用的{__list_iterator<T> tmp(*this); //直接拷贝函数、这个不用写、因为是浅拷贝,深拷贝才要写_node = _node->_next; //++(*this);return tmp;}//--Self& operator--(){_node = _node->_prev; //_node是指针return *this; //*this就是迭代器,this是指针指向迭代器}Self& operator--(int) //后置++里面就放个int,这是设计出来的伪参数,用来区分前后置用的{Self tmp(*this); //直接拷贝函数、这个不用写、因为是浅拷贝,深拷贝才要写//node = _node->_next;--(*this);return tmp;}//!=,两个迭代器之间不相等、迭代器里面的成员函数是_node,比的是这两个,就是他指向一个列表的地址,看这两个地址一样吗bool operator!=(const Self& it){return _node != it._node;}Ptr operator->(){return &_node->_data;//返回这个地址//指向这个地址,调用时第一个->返回其地址、第二个->返回地址上的值,迭代器做了优化,调用只需要一个->}};template<class T>class list{typedef __list_node<T> Node;public:typedef __list_iterator<T, T&, T*> iterator; // 放public里面不然外面动不了T,就是用不了模板,私有的不能用typedef __list_iterator<T,const T&,const T*> const_iterator;//const迭代器//迭代器用节点的指针就行了iterator begin(){return iterator(_head->_next);//注意这里返回的是迭代器,不是_head头部指针、这个是list类里面的成员变量//现在是把头部指针_head传过去,然后迭代器调用他的拷贝函数;//这里面就是构造函数、因为传过去的是Node类型;}iterator end(){return iterator(_head);}//const_iteratorconst_iterator begin() const{return const_iterator(_head->_next); }const_iterator end() const{return const_iterator(_head);}//构造函数list(){_head = new Node;//new node //这里面不用写成Node[],是因为[]是数组用的,这个就里面就开辟一个指针指向的地址空间,[]是一个数组的空间_head->_next = _head;_head->_prev = _head;}//insert//现在要的是列表里面的那两个指针next\prev;//迭代器里面就有_node存的是Node*类型;void insert(iterator pos,const T& x = T()){Node* cur = pos._node;//pos是迭代器所以调用他的成员函数用点符号"."虽然类似指针但是不能->,这个是指针用的Node* prev = cur->_prev;Node* newnode = new Node(x);newnode->_next = cur;newnode->_prev = prev;cur->_prev = newnode;prev->_next = newnode;}//头插void push_front(const T& x = T()){insert(begin(), x);}//尾插void push_back(const T& x = T()){//Node* tail = _head->_prev;//Node* newnode = new Node(x);//tail->_next = newnode;//newnode->_prev = tail;//newnode->_next = _head;//_head->_prev = newnode;//再pos是end()的时候插入,end()表示最后一个元素的后一个位置,所以插入这个位置就是尾插insert(end(), x);}//erase,erase是要返回删除的位置的后一个位置的Node* erase(iterator pos){//cur里面存现在的地址//prev是cur上一个地址assert(pos  != end()); //头节点不能删Node* cur = pos._node;  Node* prev = cur->_prev;Node* next = cur->_next;prev->_next = next;next->_prev = prev;delete cur;//delete[]必须是数组,所以要注意return next;}//尾删void pop_back(){//erase(iterator(_head->_prev));erase(--end());}//头删除void pop_front(){erase(begin());}void clear(){Node* cur = _head->_next;while (cur != _head){_head->_next = cur->_next;delete cur;cur = _head->_next}_head = head->next = head->prev;//重新关联起来,双向带头循环列表;}//析构~list(){clear();detete _head;_head = nullptr;}//拷贝函数l1(l2)//首先l1是没有创建出来的,所以要初始化list(const list<T>& lt){//先初始化,list里面成员函数是什么?_head,_head里面的内容Node* _head;_head->_next = _head->_prev = _head;//往里面插入后面的值就行了//方法一/*const_iterator it = lt.begin();while (it != it.end()){push_back(*it);//运算符重载过*it了,传过去的是_node->_datait++;}*///方法二for (auto e : lt)//本质调用的迭代器{push_back(e);}}//赋值运算l1 = l2//方法一:list<T>& operator=(const list<T>& lt){//防止自己给自己赋值if (this != &lt)//用地址来比较{clear();//看clear函数,clear结束后就是初始化后的_head,所以也不用再写一遍_head的初始话for (auto e : lt)push_back(e);//就一行不用写{}了}return *this;//*this,解引用this迭代器就是这个list类的对象了l1}//方法二:list<T>& operator=(list<T> lt)//这里传参用到拷贝构造,lt是临时对象{swap(_head, lt._head)return *this;//*this,解引用this迭代器就是这个list类的对象了l1}private:Node* _head;};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;}struct Date{int _year = 0;int _month = 1;int _day = 2;};void test_list2(){list<Date> lt;lt.push_back(Date());lt.push_back(Date());list<Date>::iterator it = lt.begin();//调用data,因为现在模板T就是date,传参传过去date是可以的while (it != lt.end()){cout << it->_year << " " << it->_month << " " << it->_day;++it;}cout << endl;}void print_list(const list<int>& lt){list<int>::const_iterator it = lt.begin();while (it != lt.end()){cout << *it << " ";++it;}cout << endl;}void test_list3(){list<int> lt;lt.push_back(1);lt.push_back(2);lt.push_back(3);lt.push_back(4);print_list(lt);lt.pop_front();lt.pop_back();print_list(lt);}
}

相关文章:

list下

文章目录 注意&#xff1a;const迭代器怎么写&#xff1f;运用场合&#xff1f; inserterase析构函数赋值和拷贝构造区别&#xff1f;拷贝构造不能写那个swap,为什么&#xff1f;拷贝构造代码 面试问题什么是迭代器失效&#xff1f;vector、list的区别&#xff1f; 完整代码 注…...

【Linux】进程间通信——system V 共享内存、消息队列、信号量

需要云服务器等云产品来学习Linux的同学可以移步/–>腾讯云<–/官网&#xff0c;轻量型云服务器低至112元/年&#xff0c;优惠多多。&#xff08;联系我有折扣哦&#xff09; 文章目录 写在前面1. 共享内存1.1 共享内存的概念1.2 共享内存的原理1.3 共享内存的使用1.3.1 …...

网络卡问题排查手段

问题 对后端来说&#xff0c;网络卡了问题&#xff0c;本身很难去排查&#xff0c;因为是 App 通过互联网连接服务 总结下&#xff0c;以往经验&#xff0c;网络卡&#xff0c;通常会有以下情况造成&#xff1a; 某地区网络问题某地区某运营商问题后端服务超载前端网络模块 …...

20240119-子数组最小值之和

题目要求 给定一个整数数组 arr&#xff0c;求 min(b) 的总和&#xff0c;其中 b 的范围涵盖 arr 的每个&#xff08;连续&#xff09;子数组。由于答案可能很大&#xff0c;因此返回答案模数 Example 1: Input: arr [3,1,2,4] Output: 17 Explanation: Subarrays are [3]…...

c# 释放所有嵌入资源, 到某个本地文件夹

版本号 .net 8 代码 using System.Reflection;namespace Demo;internal class Program {static void Main(string[] args){// 获取当前 执行exe 的目录 / 当前命令行所在的目录 var currentDir Directory.GetCurrentDirectory();Console.WriteLine(currentDir);Extract…...

Unity SnapScrollRect 滚动 匹配 列表 整页

展示效果 原理: 当停止滑动时 判断Contet的horizontalNormalizedPosition 与子Item的缓存值 相减,并得到最小值&#xff0c;然后将Content horizontalNormalizedPosition滚动过去 使用方式&#xff1a; 直接将脚本挂到ScrollRect上 注意&#xff1a;在创建Content子物体时…...

网络命令ping和telnet

1. 请解释ping和telnet的工作原理。 ping和telnet是两种常用的网络工具&#xff0c;其工作原理分别如下&#xff1a; ping&#xff1a; 目的&#xff1a;ping主要用于检查网络是否通畅以及测量网络连接速度。工作原理&#xff1a;ping是基于ICMP&#xff08;Internet Control …...

ros2学习笔记-CLI工具,记录命令对应操作。

目录 环境变量turtlesim和rqt以初始状态打开rqt node启动节点查看节点列表查看节点更多信息命令行参数 --ros-args topic话题列表话题类型话题列表&#xff0c;附加话题类型根据类型查找话题名查看话题发布的数据查看话题的详细信息查看类型的详细信息给话题发布消息&#xff0…...

自然语言处理的发展

自然语言处理的发展大致经历了四个阶段&#xff1a;萌芽期、快速发展期、低谷的发展期和复苏融合期。 萌芽期&#xff08;1956年以前&#xff09;&#xff1a;这个阶段可以看作自然语言处理的基础研究阶段。人类文明经过了几千年的发展&#xff0c;积累了大量的数学、语言学和…...

flink operator 拉取阿里云私有镜像(其他私有类似)

创建 k8s secret kubectl --namespace flink create secret docker-registry aliyun-docker-registry --docker-serverregistry.cn-shenzhen.aliyuncs.com --docker-usernameops_acr1060896234 --docker-passwordpasswd --docker-emailDOCKER_EMAIL注意命名空间指定你使用的 我…...

C语言算法赛——蓝桥杯(省赛试题)

一、十四届C/C程序设计C组试题 十四届程序C组试题A#include <stdio.h> int main() {long long sum 0;int n 20230408;int i 0;// 累加从1到n的所有整数for (i 1; i < n; i){sum i;}// 输出结果printf("%lld\n", sum);return 0; }//十四届程序C组试题B…...

【文本到上下文 #2】:NLP 的数据预处理步骤

一、说明 欢迎阅读此文&#xff0c;NLP 爱好者&#xff01;当我们继续探索自然语言处理 (NLP) 的广阔前景时&#xff0c;我们已经在最初的博客中探讨了它的历史、应用和挑战。今天&#xff0c;我们更深入地探讨 NLP 的核心——数据预处理的复杂世界。 这篇文章是我们的“完整 N…...

Minio文件分片上传实现

资源准备 MacM1Pro 安装Parallels19.1.0请参考 https://blog.csdn.net/qq_41594280/article/details/135420241 MacM1Pro Parallels安装CentOS7.9请参考 https://blog.csdn.net/qq_41594280/article/details/135420461 部署Minio和整合SpringBoot请参考 https://blog.csdn.net/…...

C语言总结十一:自定义类型:结构体、枚举、联合(共用体)

本篇博客详细介绍C语言最后的三种自定义类型&#xff0c;它们分别有着各自的特点和应用场景&#xff0c;重点在于理解这三种自定义类型的声明方式和使用&#xff0c;以及各自的特点&#xff0c;最后重点掌握该章节常考的考点&#xff0c;如&#xff1a;结构体内存对齐问题&…...

解决Spring Boot应用打包后文件访问问题

在Spring Boot项目的开发过程中&#xff0c;一个常见的挑战是如何有效地访问和操作资源文件。这一挑战尤其显著当应用从IDE环境&#xff08;如IntelliJ IDEA&#xff09;迁移到被打包成JAR文件后的生产环境。开发者经常遇到的问题是&#xff0c;在IDE中运行正常的代码&#xff…...

循环神经网络的变体模型-LSTM、GRU

一.LSTM&#xff08;长短时记忆网络&#xff09; 1.1基本介绍 长短时记忆网络&#xff08;Long Short-Term Memory&#xff0c;LSTM&#xff09;是一种深度学习模型&#xff0c;属于循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;的一种变体。…...

视频图像的color range简介

介绍 研究FFmpeg发现&#xff0c;在avcodec.h中有关于color的解释&#xff0c;主要有四个属性&#xff0c;primaries、transfer、space和range。 color primaries&#xff1a; 基于RGB空间对应的绝对颜色XYZ的变换&#xff0c;决定了最终三原色RGB分别是什么颜色&#xff1b;…...

tcp的三次握手

http 和 https 都是是基于 TCP 的请求&#xff0c;https 是 http 加上 tls 连接。TCP 是面向连接的协议。 对于 http1.1 协议chrome 限制在同一个域名下最多可以建立 6 个 tcp 连接&#xff0c;所以如果在同一个域名下&#xff0c;同时有超过 6 个请求发生&#xff0c;那么多余…...

unity 矩阵探究

public void MatrixTest1(){ ///Matrix4x4 是列矩阵&#xff0c;就是一个vector4表示一列&#xff0c;所以在c#中矩阵和Vector4只能矩阵右乘坐标。但是在shader中是矩阵左乘坐标&#xff0c;所以在shader中是行矩阵 Matrix4x4 moveMatrix1 new Matrix4x4(new Vector4(1,0,0,0)…...

MySQL---单表查询综合练习

创建emp表 CREATE TABLE emp( empno INT(4) NOT NULL COMMENT 员工编号, ename VARCHAR(10) COMMENT 员工名字, job VARCHAR(10) COMMENT 职位, mgr INT(4) COMMENT 上司, hiredate DATE COMMENT 入职时间, sal INT(7) COMMENT 基本工资, comm INT(7) COMMENT 补贴, deptno INT…...

Python项目——搞怪小程序(PySide6+Pyinstaller)

1、介绍 使用python编写一个小程序&#xff0c;回答你是猪吗。 点击“是”提交&#xff0c;弹窗并退出。 点击“不是”提交&#xff0c;等待5秒&#xff0c;重新选择。 并且隐藏了关闭按钮。 2、实现 新建一个项目。 2.1、设计UI 使用Qt designer设计一个UI界面&#xff0c…...

MySQL练习题

参考&#xff1a;https://blog.csdn.net/paul0127/article/details/82529216 数据表介绍 --1.学生表 Student(SId,Sname,Sage,Ssex) --SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别 --2.课程表 Course(CId,Cname,TId) --CId 课程编号,Cname 课程名称,TId 教师编号…...

vue-项目打包、配置路由懒加载

1. 简介 在现代前端开发中&#xff0c;Vue.js因其简洁、灵活和高效的特点&#xff0c;已经成为许多开发者的首选框架。 在Vue项目中&#xff0c;打包部署和路由懒加载是两个非常重要的环节。 打包Vue项目是为了将源代码转换为浏览器可以解析的JavaScript文件&#xff0c;以便…...

词语的魔力:语言在我们生活中的艺术与影响

Words That Move Mountains: The Art and Impact of Language in Our Lives 词语的魔力&#xff1a;语言在我们生活中的艺术与影响 Hello there, wonderful people! Today, I’d like to gab about the magical essence of language that’s more than just a chatty tool in o…...

android List,Set,Map区别和介绍

List 元素存放有序&#xff0c;元素可重复 1.LinkedList 链表&#xff0c;插入删除&#xff0c;非线性安全&#xff0c;插入和删除操作是双向链表操作&#xff0c;增加删除快&#xff0c;查找慢 add(E e)//添加元素 addFirst(E e)//向集合头部添加元素 addList(E e)//向集合…...

Mysql 编译安装部署

Mysql 编译安装部署 环境&#xff1a; 172.20.26.198&#xff08;Centos7.6&#xff09; 源码安装Mysql-5.7 大概步骤如下&#xff1a; 1、上传mysql-5.7.28.tar.gz 、boost_1_59_0.tar 到/usr/src 目录下 2、安装依赖 3、cmake 4、make && make install 5、…...

【目标检测】YOLOv5算法实现(九):模型预测

本系列文章记录本人硕士阶段YOLO系列目标检测算法自学及其代码实现的过程。其中算法具体实现借鉴于ultralytics YOLO源码Github&#xff0c;删减了源码中部分内容&#xff0c;满足个人科研需求。   本系列文章主要以YOLOv5为例完成算法的实现&#xff0c;后续修改、增加相关模…...

centos宝塔远程服务器怎么链接?

要远程连接CentOS宝塔服务器&#xff0c;可以按照以下步骤操作&#xff1a; 打开终端或远程连接工具&#xff0c;比如PuTTY。输入服务器的IP地址和SSH端口号&#xff08;默认为22&#xff09;&#xff0c;点击连接。输入用户名和密码进行登录。 如果你已经安装了宝塔面板&…...

C语言练习day8

变种水仙花 变种水仙花_牛客题霸_牛客网 题目&#xff1a; 思路&#xff1a;我们拿到题目的第一步可以先看一看题目给的例子&#xff0c;1461这个数被从中间拆成了两部分&#xff1a;1和461&#xff0c;14和61&#xff0c;146和1&#xff0c;不知道看到这大家有没有觉得很熟…...

蓝凌OA-sysuicomponent-任意文件上传_exp-漏洞复现

0x01阅读须知 技术文章仅供参考&#xff0c;此文所提供的信息只为网络安全人员对自己所负责的网站、服务器等&#xff08;包括但不限于&#xff09;进行检测或维护参考&#xff0c;未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的…...