精通C++ STL(五):list的介绍及使用

news2024/12/25 9:01:23

目录

​编辑

list的介绍

list的使用

  list的定义方式

  list的插入和删除

        push_front和pop_front

        push_back和pop_back

        insert

        erase

  list的迭代器使用

        begin和end

        rbegin和rend

  list的元素获取

        front和back

  list的大小控制

        size

        resize

        empty

        clear

  list的操作函数

        sort

        splice

        remove

        remove_if

        unique

        merge

        reverse

        assign

        swap



list的介绍

  1. list 是一种序列式容器,能在常数时间内任意位置插入和删除,并支持双向迭代
  2. list 的底层是双向链表,每个元素存储在独立结点中,结点通过指针连接前后元素
  3. listforward_list 类似,但 forward_list 是单链表,只支持单向迭代
  4. 相比其他容器,list 在任意位置插入和删除时通常更高效
  5. listforward_list 的主要缺点是无法随机访问,并且 list 需要额外空间保存结点间的关联信息,这对于存储小元素类型时尤其重要。

list的使用

  list的定义方式

方式一: 构造一个某类型的空容器。

list<int> lt1; // 构造一个空的 int 类型容器

方式二: 构造一个包含 n 个 val 的容器。

list<int> lt2(10, 2); // 构造包含 10 个 2 的 int 类型容器

方式三: 拷贝构造某类型容器的副本。

list<int> lt3(lt2); // 拷贝构造 lt2 容器的副本

方式四: 使用迭代器拷贝构造一段内容。

string s("hello world");
list<char> lt4(s.begin(), s.end()); // 拷贝构造 string 对象某段内容

方式五: 构造数组某段区间的副本。

int arr[] = {1, 2, 3, 4, 5};
int sz = sizeof(arr) / sizeof(int);
list<int> lt5(arr, arr + sz); // 构造数组某段区间的副本

  list的插入和删除

        push_front和pop_front

        push_front 函数用于在头部插入数据,而 pop_front 函数则用于删除头部的数据

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

int main()
{
	list<int> lt;
	lt.push_front(0);
	lt.push_front(1);
	lt.push_front(2);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //2 1 0
	lt.pop_front();
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 0
	return 0;
}

        push_back和pop_back

        push_back 函数用于在尾部插入数据,而 pop_back 函数则用于删除尾部的数据

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

int main()
{
	list<int> lt;
	lt.push_back(0);
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //0 1 2 3
	lt.pop_back();
	lt.pop_back();
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl;//0 1
	return 0;
}

        insert

list 中的 insert 函数支持三种插入方式

  1. 在指定迭代器位置插入一个数
  2. 在指定迭代器位置插入 n 个值为 val 的数
  3. 在指定迭代器位置插入一段迭代器区间(左闭右开)。
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	list<int>::iterator pos = find(lt.begin(), lt.end(), 2);
	lt.insert(pos, 9); //在2的位置插入9
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 9 2 3
	pos = find(lt.begin(), lt.end(), 3);
	lt.insert(pos, 2, 8); //在3的位置插入2个8
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 9 2 8 8 3
	vector<int> v(2, 7);
	pos = find(lt.begin(), lt.end(), 1);
	lt.insert(pos, v.begin(), v.end()); //在1的位置插入2个7
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //7 7 1 9 2 8 8 3
	return 0;
}

注: find 函数是头文件 <algorithm> 中的一个函数,用于在指定迭代器区间寻找指定值,并返回该位置的迭代器。 

        erase

list 中的 erase 函数支持两种删除方式

  1. 删除指定迭代器位置的元素
  2. 删除指定迭代器区间(左闭右开)内的所有元素
#include <iostream>
#include <algorithm>
#include <vector>
#include <list>
using namespace std;

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);
	list<int>::iterator pos = find(lt.begin(), lt.end(), 2);
	lt.erase(pos); //删除2
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 3 4 5
	pos = find(lt.begin(), lt.end(), 4);
	lt.erase(pos, lt.end()); //删除4及其之后的元素
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 3
	return 0;
}

  list的迭代器使用

        begin和end

        通过 begin 函数可以得到容器中第一个元素的正向迭代器,而 通过 end 函数可以得到容器中最后一个元素的后一个位置的正向迭代器

正向迭代器遍历容器:

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

int main()
{
	list<int> lt(10, 2);
	//正向迭代器遍历容器
	list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;
	return 0;
}

        rbegin和rend

        通过 rbegin 函数可以得到容器中最后一个元素的反向迭代器,而 通过 rend 函数可以得到容器中第一个元素的前一个位置的反向迭代器

反向迭代器遍历容器:

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

int main()
{
	list<int> lt(10, 2);
	//反向迭代器遍历容器
	list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		rit++;
	}
	cout << endl;
	return 0;
}

  list的元素获取

        front和back

        front 函数用于获取 list 容器中的第一个元素,而 back 函数用于获取 list 容器中的最后一个元素

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

int main()
{
	list<int> lt;
	lt.push_back(0);
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	cout << lt.front() << endl; //0
	cout << lt.back() << endl; //4
	return 0;
}

  list的大小控制

        size

        size 函数用于获取当前容器中的元素个数

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

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	cout << lt.size() << endl; //4
	return 0;
}

        resize

resize 的两种情况:

  1. 当所给值大于当前的 size 时,将 size 扩大到该值,扩大的数据为第二个所给值,如果未给出,则默认为容器存储类型的默认构造值。
  2. 当所给值小于当前的 size 时,将 size 缩小到该值
#include <iostream>
#include <list>
using namespace std;

int main()
{
	list<int> lt(5, 3);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //3 3 3 3 3
	lt.resize(7, 6); //将size扩大为7,扩大的值为6
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //3 3 3 3 3 6 6
	lt.resize(2); //将size缩小为2
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //3 3
	return 0;
}

        empty

        empty 函数用于判断当前容器是否为空

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

int main()
{
	list<int> lt;
	cout << lt.empty() << endl; //1
	return 0;
}

        clear

        clear 函数用于清空容器,清空后容器的 size 为 0

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

int main()
{
	list<int> lt(5, 2);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //2 2 2 2 2
	cout << lt.size() << endl; //5
	lt.clear(); //清空容器
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //(无数据)
	cout << lt.size() << endl; //0
	return 0;
}

  list的操作函数

        sort

        sort 函数可以将容器中的数据默认按升序排序

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

int main()
{
	list<int> lt;
	lt.push_back(4);
	lt.push_back(7);
	lt.push_back(5);
	lt.push_back(9);
	lt.push_back(6);
	lt.push_back(0);
	lt.push_back(3);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //4 7 5 9 6 0 3
	lt.sort(); //默认将容器内数据排为升序
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //0 3 4 5 6 7 9
	return 0;
}

        splice

splice 函数用于在两个 list 容器之间进行拼接,其有三种拼接方式:

  1. 将整个容器拼接到另一个容器的指定迭代器位置
  2. 将容器中的某一个数据拼接到另一个容器的指定迭代器位置
  3. 将容器指定迭代器区间的数据拼接到另一个容器的指定迭代器位置
#include <iostream>
#include <list>
using namespace std;

int main()
{
	list<int> lt1(4, 2);
	list<int> lt2(4, 6);
	lt1.splice(lt1.begin(), lt2); //将容器lt2拼接到容器lt1的开头
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl; //6 6 6 6 2 2 2 2 

	list<int> lt3(4, 2);
	list<int> lt4(4, 6);
	lt3.splice(lt3.begin(), lt4, lt4.begin()); //将容器lt4的第一个数据拼接到容器lt3的开头
	for (auto e : lt3)
	{
		cout << e << " ";
	}
	cout << endl; //6 2 2 2 2 

	list<int> lt5(4, 2);
	list<int> lt6(4, 6);
	lt5.splice(lt5.begin(), lt6, lt6.begin(), lt6.end()); //将容器lt6的指定迭代器区间内的数据拼接到容器lt5的开头
	for (auto e : lt5)
	{
		cout << e << " ";
	}
	cout << endl; //6 6 6 6 2 2 2 2
	return 0;
}

注意: 容器中被拼接到另一个容器的数据在原容器中 不再存在。(实际上,指定的结点被从链表中移除,并拼接到另一个容器)。 

        remove

        remove 函数用于删除容器中所有具有特定值的元素

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

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(4);
	lt.push_back(3);
	lt.push_back(3);
	lt.push_back(2);
	lt.push_back(2);
	lt.push_back(3);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 4 3 3 2 2 3
	lt.remove(3); //删除容器当中值为3的元素
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 4 2 2
	return 0;
}

        remove_if

        remove_if 函数用于删除容器中所有满足特定条件的元素

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

bool single_digit(const int& val)
{
	return val < 10;
}
int main()
{
	list<int> lt;
	lt.push_back(10);
	lt.push_back(4);
	lt.push_back(7);
	lt.push_back(18);
	lt.push_back(2);
	lt.push_back(5);
	lt.push_back(9);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //10 4 7 18 2 5 9
	lt.remove_if(single_digit); //删除容器当中值小于10的元素
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //10 18
	return 0;
}

        unique

        unique 函数用于删除容器中连续的重复元素

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

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(4);
	lt.push_back(3);
	lt.push_back(3);
	lt.push_back(2);
	lt.push_back(2);
	lt.push_back(3);
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 4 3 3 2 2 3
	lt.sort(); //将容器当中的元素排为升序
	lt.unique(); //删除容器当中连续的重复元素
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //1 2 3 4
	return 0;
}

注意: 若要真正实现去重,还需在调用 unique 函数前对容器内的元素进行排序。

        merge

        merge 函数用于将一个有序 list 容器合并到另一个有序 list 容器中,使得合并后的容器仍然保持有序状态(类似于归并排序)。

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

int main()
{
	list<int> lt1;
	lt1.push_back(3);
	lt1.push_back(8);
	lt1.push_back(1);
	list<int> lt2;
	lt2.push_back(6);
	lt2.push_back(2);
	lt2.push_back(9);
	lt2.push_back(5);
	lt1.sort(); //将容器lt1排为升序
	lt2.sort(); //将容器lt2排为升序
	lt1.merge(lt2); //将lt2合并到lt1当中
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl; //1 2 3 5 6 8 9 
	return 0;
}

        reverse

        reverse 函数用于将容器中元素的位置逆置

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

int main()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);
	lt.reverse(); //将容器当中元素的位置进行逆置
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //5 4 3 2 1 
	return 0;
}

        assign

assign 函数用于将新内容分配给容器,替换其当前内容,赋予新内容的方式有两种:

  1. n 个值为 val 的数据分配给容器
  2. 将所给迭代器区间中的内容分配给容器
#include <iostream>
#include <string>
#include <list>
using namespace std;

int main()
{
	list<char> lt(3, 'a');
	lt.assign(3, 'b'); //将新内容分配给容器,替换其当前内容
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //b b b
	string s("hello world");
	lt.assign(s.begin(), s.end()); //将新内容分配给容器,替换其当前内容
	for (auto e : lt)
	{
		cout << e << " ";
	}
	cout << endl; //h e l l o   w o r l d
	return 0;
}

        swap

        swap 函数用于交换两个容器的内容

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

int main()
{
	list<int> lt1(4, 2);
	list<int> lt2(4, 6);
	lt1.swap(lt2); //交换两个容器的内容
	for (auto e : lt1)
	{
		cout << e << " ";
	}
	cout << endl; //6 6 6 6
	for (auto e : lt2)
	{
		cout << e << " ";
	}
	cout << endl; //2 2 2 2
	return 0;
}

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

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

相关文章

内部排序(插入、交换、选择)

一、排序的部分基本概念 1. 算法的稳定性 若待排序表中有两个元素 Ri 和 Rj &#xff0c;其对应的关键字相同即 keyi keyj&#xff0c;且在排序前 Ri 在 Rj 的前面&#xff0c;若使用某一排序算法排序后&#xff0c;Ri 仍然在 Rj 的前面&#xff0c;则称这个排序算法是稳定的…

EMC学习笔记4——传导骚扰发射

传导骚扰发射是最基本的实验项目&#xff0c;主要是检测设备在工作时是否通过电源线产生过强的骚扰发射。 一、传导骚扰发射判断 可以通过两个方面来判断设备是否产生了传导发射&#xff1a; 1.电流的时域波形判断&#xff1a;电流波形与电压的波形不一样。如下图所示&#xf…

界面控件DevExpress .NET MAUI v24.1 - 发布TreeView等新组件

DevExpress拥有.NET开发需要的所有平台控件&#xff0c;包含600多个UI控件、报表平台、DevExpress Dashboard eXpressApp 框架、适用于 Visual Studio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress 今年第一个重要版本v23.1正式发布&#xff0c;该版本拥有众多…

探索谜题,畅享推理——海龟汤智能体来袭

本文由 ChatMoney团队出品 介绍说明 在神秘与智慧交织的世界里&#xff0c;有一种游戏能让您的思维飞速旋转&#xff0c;激发无限的想象力和推理能力&#xff0c;那就是海龟汤。现在&#xff0c;我们为您带来全新的海龟汤智能体&#xff0c;为您的娱乐时光增添无尽乐趣&#x…

YOLOv5改进 | 融合改进 | C3融合动态卷积模块ODConv【完整代码】

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录&#xff1a; 《YOLOv5入门 改…

学生高性价比运动耳机有哪些?五大性价比高的运动耳机学生党分享

2024年春季&#xff0c;开放式蓝牙耳机就凭借“佩戴舒适、开放安全”等优势火热出圈&#xff0c;这让各大音频厂商更新迭代速度不断加快&#xff0c;新品层出不穷。而用户面对市场上琳琅满目的开放式蓝牙耳机&#xff0c;一时间也不知道如何选择。对于学生来说&#xff0c;比较…

RepQ-ViT 阅读笔记

RepQ-ViT: Scale Reparameterization for Post-Training Quantization of Vision Transformers ICCV 2023 中国科学院自动化研究所 Abstract RepQ-ViT&#xff0c;一种新的基于量化缩放因子&#xff08;quantization scale&#xff09;重参数化的PTQ框架 解耦量化和推理过程…

ios使用plist实现相册功能

第一步&#xff1a;照片复制到Assets文件夹再创建plist 第二步&#xff1a;页面设计 第三步&#xff1a;代码实现 // // PhotoViewController.m // study2024 // // Created by zhifei zhu on 2024/8/11. //#import "PhotoViewController.h"interface PhotoView…

JAVA打车小程序APP打车顺风车滴滴车跑腿源码微信小程序打车系统源码

&#x1f697;&#x1f4a8;打车、顺风车、滴滴车&跑腿系统&#xff0c;一键解决出行生活难题&#xff01; 一、出行新选择&#xff0c;打车从此不再难 忙碌的生活节奏&#xff0c;让我们常常需要快速、便捷的出行方式。打车、顺风车、滴滴车系统&#xff0c;正是为了满足…

通天星CMSV6代码审计

fofa指纹 body"./open/webApi.html"||body"/808gps/" /gpsweb/WEB-INF/classes/config/version.conf中可以查看版本。 框架分析 默认安装目录为C:\Program Files\CMSServerV6\ 默认账户&#xff1a;admin/admin 框架结构 跟进web.xml&#xff0c;可以看…

WebGL 入门:开启三维网页图形的新篇章(上)

一、引言 介绍 WebGL 的背景和意义 一、背景 WebGL 是一种 JavaScript API&#xff0c;用于在网页上呈现三维图形。 它是在 2009 年由 Khronos Group 提出的&#xff0c;并于 2011 年成为 W3C 的标准。 在 WebGL 出现之前&#xff0c;网页上的三维图形主要是通过插件&…

TEMU卖家们如何提高temu店铺排名、权重、流量、采购测评成功率?

一、什么叫做自养号测评&#xff1f; 自养号测评类似于国内的某宝S单&#xff0c;就是通过搭建海外的服务器和IP采用海外真实买家资料来注册、养号、下单。 二、自养号测评有哪些作用&#xff1f; 自养号快速提高产品的排名、权重和销量&#xff0c;可以提升订单量、点赞(rat…

Excel工作表同类数据合并工具

下载地址&#xff1a;https://pan.quark.cn/s/81b1aeb45e4c 在Excel表格中&#xff0c;把多行同类数据合并为一行是件令人无比头痛的事情&#xff1a;首先&#xff0c;你得确定哪几条记录是可合并的同类数据&#xff0c;人工对比多个字段难免顾此失彼挂一漏万&#xff1b;其次&…

【深度学习】【文本LLM】如何使用文本相似度挑选语料?

在GitHub上挑选和优化语料库的开源工具与方法 在GitHub上挑选和优化语料库的开源工具与方法 在数据科学和自然语言处理(NLP)的世界里,拥有一个干净且高质量的语料库是成功的关键。然而,随着数据量的增加,处理和优化这些数据变得尤为重要。幸运的是,GitHub上提供了许多开…

分享一个基于SpringBoot的戏剧戏曲科普平台的设计与实现(源码、调试、LW、开题、PPT)

&#x1f495;&#x1f495;作者&#xff1a;计算机源码社 &#x1f495;&#x1f495;个人简介&#xff1a;本人 八年开发经验&#xff0c;擅长Java、Python、PHP、.NET、Node.js、Android、微信小程序、爬虫、大数据、机器学习等&#xff0c;大家有这一块的问题可以一起交流&…

汇编语言:loop指令

loop指令是循环指令&#xff0c;在8086CPU中&#xff0c;所有的循环指令都是短转移&#xff0c;其对应的机器指令有2个字节&#xff0c;低8位字节存放的是操作码&#xff1b;高8位字节存放的是转移位移&#xff08;相对于当前IP的位移&#xff09;&#xff0c;用补码形式表示&a…

C# NetworkStream、ConcurrentDictionary、Socket类、SerialPort、局域网IP 和广域网IP

一、NetworkStream 什么是NetworkStream&#xff1f; NetworkStream 是 .NET Framework 中用于在网络上进行数据传输的流类。它属于System.Net.Sockets 命名空间&#xff0c;并提供了通过网络连接进行读写操作的功能。NetworkStream 主要用于处理从网络套接字&#xff08;Soc…

input 控制光标所在的位置

需求&#xff1a;鼠标一点击input输入框 就要将焦点至于 输入框的最后面&#xff0c;使用户不能在内容的中间 删除或者修改 const focusEnd (value) > {var inpEl value.target // 获取dom元素console.log(inpEl, LLL);var length value.target.value.length // 获取输入…

【Hot100】LeetCode—48. 旋转图像

目录 1- 思路两次遍历实现&#xff08;先行&#xff0c;后主对角互换&#xff09; 2- 实现⭐48. 旋转图像——题解思路 3- ACM 实现 原题连接&#xff1a;48. 旋转图像 1- 思路 两次遍历实现&#xff08;先行&#xff0c;后主对角互换&#xff09; 技巧&#xff1a;旋转 90 …

通过反汇编解析crash问题

背景: 用户反馈的问题&#xff0c;有时候我们拿到log&#xff0c;发现有crash问题&#xff0c;有堆栈打印&#xff0c;能看到具体出错的函数&#xff0c;但是无法定位具体出错的行数和内容&#xff0c;这个时候就需要用到反汇编辅助我们定位问题。 反汇编方法: 通过objdump反汇…