list常见接口的使用(基于c++标准库中的STL)

news2024/12/27 12:38:27

前言 

        list是重要的容器了解它的常见接口以及使用是很有必要的,为什么有了vector还要有list呢?因为vector存在一些缺陷,比如:容量满了要扩容,扩容是要付出代价的(性能的损失),存在空间的浪费,而且vector的头删头插或者中间位置的插入删除都需要挪动数据(时间复杂度O(n))因此比较慢。而list的存在就是为了弥补vector的缺点,list不需要扩容,不存在空间的浪费,任意位置的插入和删除都很快(时间复杂度为(O1))。下面让我们一起来了解一下list的使用吧!

目录

1.构造函数

2.迭代器

3.插入删除

4.容量相关

        4.1容量相关

        4.2取出表头表尾数据

5.list的迭代器失效


1.构造函数

         

例如:

void testList1()
{
	list<int>l1;//构造空的对象
	list<int>l2(5, 2);//构造5个val值的对象
	list<int>l3(l2);//拷贝构造

	//尾删尾插
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_back(5);

	l1.pop_back();
	//迭代器正向遍历
	list<int>::iterator it = l1.begin();
	while (it != l1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	//范围for
	for (auto e : l2)
	{
		cout << e << " ";
	}
}

2.迭代器

         

void testList1()
{
	list<int>l1;//构造空的对象
	list<int>l2(5, 2);//构造5个val值的对象
	list<int>l3(l2);//拷贝构造

	//尾删尾插
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_back(5);

	l1.pop_back();
	//迭代器正向遍历
	list<int>::iterator it = l1.begin();
	while (it != l1.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	//范围for
	for (auto e : l2)
	{
		cout << e << " ";
	}
}
void print(const list<int>& l1);
void testList2()
{
	list<int> l1;
	//头插头删
	l1.push_front(0);
	l1.push_front(-1);
	l1.push_front(-2);
	l1.push_front(-3);
	l1.push_front(-4);
	l1.push_front(-5);

	l1.pop_front();
	l1.pop_front();

	//迭代器逆向循环
	list<int>::reverse_iterator it = l1.rbegin();
	while (it != l1.rend())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	print(l1);
}
void print(const list<int>& l1)
{
	//const类型的迭代器
	list<int>::const_iterator it = l1.cbegin();
	while (it != l1.cend())
	{
		//*it += 1;
		cout << *it << " ";
		it++;
	}
}

        注意const类型的对象遍历需要const类型的迭代器,如上。

        范围for是靠迭代器支持的,所以支持迭代器就支持范围for(c++11语法)。

        begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动

        rbegin和rend为反向迭代器。对迭代器执行++操作,迭代器向前移动 

3.插入删除

list接口说明
push_back在list的尾部插入一个值为val的元素
pop_back删除list尾部的元素
push_front在list的第一个元素之前插入值为val的元素
pop_back删除list的第一个元素
insert任意位置的插入
erase任意合法位置的删除
swap交换两个list中的元素
clear清空list中的有效元素

        例如:

void testList2()
{
	list<int> l1;
	//头插头删
    //尾删尾插
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_back(5);

	l1.pop_back();
	l1.push_front(0);
	l1.push_front(-1);
	l1.push_front(-2);
	l1.push_front(-3);
	l1.push_front(-4);
	l1.push_front(-5);

	l1.pop_front();
	l1.pop_front();

	//迭代器逆向循环
	list<int>::reverse_iterator it = l1.rbegin();
	while (it != l1.rend())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	
}
void testList3()
{
	//
	list<int> l1;
	
	l1.insert(l1.begin(), 1);//调用insert头插 
	l1.insert(l1.begin(), 2);
	l1.insert(l1.begin(), 3); 
	l1.insert(l1.begin(), 4);
	l1.insert(l1.begin(), 5); 
	l1.insert(l1.begin(), 6);
	for (auto& e : l1)
	{
		cout << e << "->";
	}
	cout << endl;
	l1.insert(l1.end(), 10);//用insert尾插
	l1.insert(l1.end(), 20);
	l1.insert(l1.end(), 30);
	l1.insert(l1.end(), 40);

	l1.erase(--l1.end());//调用erase尾删
	for (auto& e : l1)
	{
		cout << e << "->";
	}
	cout << endl;
	list<int>l2(6, -2);//构造6个2
	cout << "l2交换前:" << endl;
	for (auto& e : l2)
	{
		cout << e << "->";
	}
	cout << endl;
	swap(l1, l2);//交换l1和l2
	cout << "l2交换后:" << endl;
	for (auto& e : l2)
	{
		cout << e << "->";
	}
	cout << endl;
	l2.clear();//清空l2
	for (auto& e : l2)
	{
		cout << e << "->";
	}
	cout << endl;
}

        注意list是不支持随机访问的,所以在调用erase和insert,迭代器不能加一个常数传给erase和insert ,如:

    list<int> l1;
	
	l1.insert(l1.begin(), 1);//调用insert头插 
	l1.insert(l1.begin(), 2);
	l1.insert(l1.begin(), 3); 
	l1.insert(l1.begin(), 4);
	l1.insert(l1.begin(), 5); 
	l1.insert(l1.begin(), 6);
    //下面这两个是错误的用法
    l1.insert(l1.end()+5, 40);

    l1.erase(l1.end()-3);//调用erase尾删

        insert的函数原型:

使用它要给它一个迭代器,不管是插入一个val还是n个val。

        erase的函数原型: 

给它的如果是一个迭代器删除的就是这个迭代器位置的val,如果是一段迭代器区间删除的就是这段迭代器区间的val。注意不能传end() 给它,程序会奔溃,因为end()迭代器实际上是头结点,在list对象生命周期没有结束的时候头结点是不可以被删除的,不然如果后面再去操作这个链表就会有内存访问冲突的问题。

4.容量相关

        4.1容量相关

函数说明接口说明
empty判断链表是否为空如果为空返回true,反之返回false
size返回list中有效节点的个数

 

void testList4()
{
	//
	list<int> l1;

	l1.insert(l1.begin(), 1);//调用insert头插 
	l1.insert(l1.begin(), 2);
	l1.insert(l1.begin(), 3);
	l1.insert(l1.begin(), 4);
	l1.insert(l1.begin(), 5);
	l1.insert(l1.begin(), 6);
	for (auto& e : l1)
	{
		cout << e << "->";
	}
	cout << endl;
	cout << l1.size() << endl;
	while (!l1.empty())//删除链表表头元素的方式遍历链表元素
	{
		cout << l1.front() << "->";//取出表头元素
		l1.pop_front();//删除头节点
	}
	cout << endl;
}

        4.2取出表头表尾数据

         

front和back
函数声明接口说明
front返回list第一个节点中值的引用
back返回list最后一个节点中值的引用

         例如:

void testList5()
{
	//
	list<int> l1;

	l1.insert(l1.begin(), 1);//调用insert头插 
	l1.insert(l1.begin(), 2);
	l1.insert(l1.begin(), 3);
	l1.insert(l1.begin(), 4);
	l1.insert(l1.begin(), 5);
	l1.insert(l1.begin(), 6);
	cout << l1.front() << endl;//输出链表第一个节点的值
	cout << l1.back() << endl;//输出链表最后一个节点的值
}

5.list的迭代器失效

        当我们在迭代器的某个位置插入一个元素迭代器会失效吗?请和我一起看看下面的代码!

void testList5()
{
	list<int> l1;
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_back(5);
	l1.push_back(6);
	l1.push_back(7);
	list<int>::iterator it = l1.begin();
	it++;//到下一个节点的迭代器
	l1.insert(it, -4);//在这个迭代器这里插入一个val值迭代器会失效
    l1.insert(it, -5);//在这里继续插入一个val值程序会奔溃吗?
}

         实际上在list中插入元素迭代器是不会失效的。这与list的物理结构有关,因为插入一个节点,原来的节点是没有删除的,只是申请了一个新的节点然后与原来的节点建立联系,插入数据。

        如果删除一个元素呢?我们来试试

void testList7()
{
	list<int> l1;
	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_back(5);
	l1.push_back(6);
	l1.push_back(7);
	list<int>::iterator it = l1.begin();
	l1.erase(it);//删除节点的元素
	l1.insert(it,-4);
}

如果删除了这个节点,那么再对这个节点的迭代器进行操作程序就会报错,实际上这块内存已经被delete了,所以已经返还给操作系统了再进行其他操作就是不被允许的了。

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

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

相关文章

【Leetcode -724.寻找数组的中心下标 -728.自除数】

Leetcode Leetcode -724.寻找数组的中心下标Leetcode -728.自除数 Leetcode -724.寻找数组的中心下标 题目&#xff1a;给你一个整数数组 nums &#xff0c;请计算数组的 中心下标 。 数组 中心下标 是数组的一个下标&#xff0c;其左侧所有元素相加的和等于右侧所有元素相加的…

【网络编程】一文详解http协议(超文本传输协议)

目录 一、http协议 1、http协议的介绍 2、URL的组成 3、urlencode和urldecode 二、http的请求方法、状态码及状态码描述、常见的响应报头 1、http请求方法 2、http状态码及状态码描述 3、http常见的响应报头 三、http协议客户端和服务器的通信过程 1、如何保证请求和…

驱动LSM6DS3TR-C实现高效运动检测与数据采集(2)----配置滤波器

工作模式 在LSM6DS3TR-C中&#xff0c;加速度计和陀螺仪可以独立地开启/关闭&#xff0c;并且可以拥有不同的ODR和功耗模式。 LSM6DS3TR-C有三种可用的操作模式&#xff1a; ● 仅加速度计活动&#xff0c;陀螺仪处于断电状态 ● 仅陀螺仪活动&#xff0c;加速度计处于断电状态…

chatgpt赋能python:Python中0.2+0.1的问题解决方案

Python中0.20.1的问题解决方案 在Python中&#xff0c;0.20.1的结果并非等于0.3。这是由于计算机在二进制中存储小数时会存在精度问题导致的。而这个问题在日常编程中可能并不会带来太大的影响&#xff0c;但在需要精确计算的场景下&#xff0c;如金融或科学领域&#xff0c;就…

第 2 章:Vue 组件化编程

目录 模块与组件、模块化与组件化 模块 组件 模块化 组件化 非单文件组件 小结 组件的几个注意点 组件的嵌套 VueComponent构造函数 小结 一个重要的内置关系 小结 单文件组件 一个.vue 文件的组成(3 个部分) 1. 模板页面 2. JS 模块对象 3. 样式 基本使用 模…

chatgpt赋能python:Python中4+5的结果是多少?

Python中45的结果是多少&#xff1f; Python是一种高级的编程语言&#xff0c;由它所支持的各种库和框架&#xff0c;可以对不同的业务场景进行快速、高效的处理。在Python中&#xff0c;基本的运算符包括加、减、乘、除等&#xff0c;其中加操作是一个非常基本的操作&#xf…

chatgpt赋能python:Python中isin函数的使用方法

Python中isin函数的使用方法 Python是一种流行的编程语言&#xff0c;被广泛使用于数据分析、Web应用程序和游戏开发等领域。其中&#xff0c;Python的算法和数据结构库为程序员提供了实用的工具&#xff0c;使得数据的筛选、排序和搜索操作更加简易。Python之中的isin函数&am…

浅尝RTSP

RTSP (real time streaming protocol) RTC2326 RTSP 实时流传输协议,是TCP/IP 协议体系中的一个应用层协议,由哥伦比亚大学, 网景和realnetworks公司提交的IETF RTC 标准&#xff0c;该协议定义了一对多应用程序如何有效地通过IP网络传送多媒体数据。 RTSP在体系结构上位于 rtp…

二分搜索树层序遍历

二分搜索树的层序遍历&#xff0c;即逐层进行遍历&#xff0c;即将每层的节点存在队列当中&#xff0c;然后进行出队&#xff08;取出节点&#xff09;和入队&#xff08;存入下一层的节点&#xff09;的操作&#xff0c;以此达到遍历的目的。 通过引入一个队列来支撑层序遍历…

【SpringBoot】整合Mybatis-Plus并输出SQL日志

目录 本地开发环境说明pom.xml主要依赖application.yml主要配置MapperScan注解使用说明实体类示例Mapper接口示例Service接口示例Service接口实现类示例单元测试示例打印SQL日志使用slf4j打印SQL 总结 本地开发环境说明 开发依赖版本Spring Boot3.0.6Mybatis-Plus3.5.3.1JDK20…

git客户端的使用

1. git 分布式版本控制工具。 具有中央服务器仓库和本地仓库。 客户端下载&#xff1a;GitHub Desktop | Simple collaboration from your desktop 2. git的使用 2.1 修改操作本地仓库的用户信息 2.2 创建本地仓库 左上角&#xff1a;File - New repository 本地的两个仓库…

chatgpt赋能python:Python中4.5/2:浮点数除法的谬误

Python中4.5/2&#xff1a;浮点数除法的谬误 在Python中&#xff0c;当我们尝试对两个整数进行除法运算时&#xff0c;通常可以得到预期的正确结果。但是&#xff0c;当我们的被除数或者除数是浮点数时&#xff0c;可能会遇到令人疑惑的结果。 例如&#xff0c;执行4.5/2的计…

chatgpt赋能python:Python中Delete的用法及其重要性

Python中Delete的用法及其重要性 Python是一种强大的编程语言&#xff0c;它提供了许多强大的工具和API&#xff0c;帮助程序员轻松编写高效的代码。其中&#xff0c;Delete是Python语言中一个非常重要的关键字&#xff0c;用于删除对象和变量。 Delete的用法 Delete作为Pyt…

chatgpt赋能python:Python中IDLE怎么执行代码

Python中IDLE怎么执行代码 介绍 作为一种非常流行的编程语言&#xff0c;Python可以编写各种应用程序&#xff0c;从自动化脚本到网站后端。无论您是一个新手还是一个经验丰富的程序员&#xff0c;您都可能会使用Python编程语言来完成您的工作。 一个好的Python IDE可以大大…

sql的各种排序(order by加asc或者desc、order by加field()加asc或者desc)

sql的各种排序&#xff08;order by加asc或者desc、order by加field()加asc或者desc&#xff09; 1.单字段排序&#xff1b; 【order by】排序&#xff1a;order by后面跟着的字段就是数据的排序字段&#xff1b; &#xff08;1&#xff09;升序排序&#xff1b; 举例&#x…

c++—封装:构造函数、析构函数、成员操作

1. 封装的主要目的是解决代码的维护性问题&#xff0c;经过封装的函数代码独立性高&#xff1b; 2. 封装的演变历史&#xff0c;以栈为例子介绍&#xff1a; ①成员&#xff08;top、data[ ]&#xff09;都在main函数里&#xff0c;动作方法&#xff08;push、pop&#xff09;…

力扣sql中等篇练习(二十八)

力扣sql中等篇练习(二十八) 1 每个城市最高气温的第一天 1.1 题目内容 1.1.1 基本题目信息 1.1.2 示例输入输出 1.2 示例sql语句 # Write your MySQL query statement below SELECT w.city_id,MIN(w.day) day,w.degree FROM Weather w INNER JOIN (SELECT city_id,MAX(degr…

chatgpt赋能python:Python中keys的概述

Python中keys的概述 在Python中&#xff0c;字典&#xff08;dictionary&#xff09;是一种非常常见的数据结构&#xff0c;它由一系列键&#xff08;keys&#xff09;和对应值&#xff08;values&#xff09;组成。键是唯一的&#xff0c;而值可以重复。在字典中&#xff0c;…

Lucene基础学习

一、基础知识 1.Lucene简介 2.入门实例 3.内建Query对象 4.分析器Analyzer 5.Query Parser 6.索引 7.排序 8.过滤 9.概念简介 10.Lucene入门实例 二、Lucene的基础 三、索引建立 1.lucene索引_创建_域选项 2.lucene索引_的删除和更新 3.lucene索引_加权操作和Luke的简单演示…

msvcp140.dll丢失怎么办?msvcp140.dll重新安装的解决方法

msvcp140.dll是微软编译器系统中的一个动态链接库文件&#xff0c;它存储了许多的代码和数据&#xff0c;能帮助计算机程序正常运行。当系统中出现了msvcp140.dll丢失的情况时&#xff0c;则会出现程序无法正常运行的错误。这篇文章将为大家介绍如何解决msvcp140.dll丢失的问题…