STL值list

list容器

头文件:#include<list>

  • list是一个双向链表容器,可高效地进行插入删除元素

  • list不可以随机存取元素,所以不支持at.(pos)函数与\[\]操作符

注:list使用迭代器访问数据时可以一步一步走自增自减(即it++)不允许跨太多步去访问元素

list容器是可以进行遍历的,即进行数据访问时不会进行删除操作

list头尾的添加移除操作

  • list.push back(elem); //在容器尾部加入一个元素

  • list.pop _back(); //删除容器中最后一个元素

  • list.push front(elem); //在容器开头插入一个元素

  • list.pop_front(); //从容器开头移除第一个元素

list的数据存取

list.front();//返回第一个元素。

list.back(); //返回最后一个元素。

list与迭代器

  • list 容器的迭代器是"双向迭代器":双向迭代器从两个方向读写容器。除了提供前向迭代器的全部操作之外,双向迭代器还提供前置和后置的自减运算。

  • list.begin(); //返回容器中第一个元素的选代器

  • list.end(); //返回容器中最后一个元素之后的迭代器

  • list.rbegin(); //返回容器中倒数第一个元素的选代器

  • list.rend(); //返回容器中倒数最后一个元素的后面的选代器

示例1:list与正向迭代器

cpp 复制代码
#include<iostream>
#include<list>
using namespace std;
int main() {
	list<int> lst;
	lst.push_back(10);
	lst.push_front(20);

	list<int>::iterator it;
	for (it = lst.begin(); it != lst.end(); it++) {
		cout << *it << ' ';
	}
	cout << endl;


	int a = lst.front();
	cout << "front:" << a << endl;

	int b = lst.back();
	cout << "back:" << b << endl;
	
	//修改容器末尾和首部的值
	lst.front() = 100;
	lst.back() = 200;
	a = lst.front();
	cout << "front:" << a << endl;

	b = lst.back();
	cout << "back:" << b << endl;
}

示例2:list与反向迭代器

cpp 复制代码
#include<iostream>
#include<list>
using namespace std;
int main() {
	list<int> lst;
	lst.push_back(10);
	lst.push_front(20);
	list<int>::reverse_iterator it1;
	for (it1 = lst.rbegin(); it1 != lst.rend(); it1++) {
		cout << *it1 << ' ';
	}
	cout << endl;
	
}

list对象的带参数构造

  • list(n,elem); //构造函数将n个elem拷贝给本身

  • list(beg,end); //构造函数将[beg,end)区间中的元素拷贝给本身

  • list(const list &lst); //拷贝构造函数。

cpp 复制代码
#include<iostream>
#include<list>
using namespace std;
int main() {
	list<int>::iterator it;
	list<int> lst(3, 5);
	for (it = lst.begin(); it != lst.end(); it++) {
		cout << *it << ' ';
	}
	cout << endl;

	list<int> lst2(lst.begin(),lst.end());
	//list<int> lst2(lst.begin(), lst.begin()+5);错误
	for (it = lst2.begin(); it != lst2.end(); it++) {
		cout << *it << ' ';
	}
	cout << endl;

	int a[] = { 1,2,3,4,5 };
	list<int> lst3(a, a + 5);
	for (it = lst3.begin(); it != lst3.end(); it++) {
		cout << *it << ' ';
	}
	cout << endl;

	list<int> lst4(lst);
	for (it = lst4.begin(); it != lst4.end(); it++) {
		cout << *it << ' ';
	}
	cout << endl;
}

list的赋值

  • list.assign(beg,end); //将[beg,end)区间中的数据拷贝赋值给本身。注意该区间是左闭右开的区间。

  • list.assign(n,elem); //将n个elem拷贝赋值给本身

  • list& operator=(const list &lst); //重载等号操作符

  • list.swap(lst); // 将lst与本身的元素互换。

示例:

cpp 复制代码
#include<iostream>
#include<list>
using namespace std;
int main() {
	
	list<int> lst1,lst2;
	list<int> lst3 = { 1,2,3,4,5 };
	list<int>::iterator it = lst3.end();
	list<int>::iterator it2;
	lst1.assign(lst3.begin(), it);
	for (it2 = lst1.begin(); it2 != lst1.end(); it2++) {
		cout << *it2 << ' ';
	}
	cout << endl;
	cout << endl;

	lst2.assign(3, 5);
	for (it2 = lst2.begin(); it2 != lst2.end(); it2++) {
		cout << *it2 << ' ';
	}
	cout << endl;
	cout << endl;

	lst2 = lst1;
	for (it2 = lst1.begin(); it2 != lst1.end(); it2++) {
		cout << *it2 << ' ';
	}
	cout << endl;
	cout << endl;

	lst1.swap(lst2);
	for (it2 = lst1.begin(); it2 != lst1.end(); it2++) {
		cout << *it2 << ' ';
	}
	cout << endl;
	for (it2 = lst2.begin(); it2 != lst2.end(); it2++) {
		cout << *it2 << ' ';
	}
	cout << endl;

}

list的大小

  • list.size(); //返回容器中元素的个数

  • list.empty(); //判断容器是否为空

  • list.resize(num); //重新指定容器的长度为num,若容器变长,则以默认值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

  • list.resize(num,elem); //重新指定容器的长度为num,若容器变长,则以elem值填充新位置。如果容器变短,则末尾超出容器长度的元素被删除。

list的插入

  • list.insert(pos,elem)//在pos位置插入一个elem元素的拷贝,返回新数据的位置

  • list.insert(pos,n,elem);//在pos位置插入n个elem数据,无返回值

  • list.insert(pos,beg,end);//在pos位置插入[beg,end)区间的数据,无返回值

注:list进行数据的插入时是没有空间的释放和位置的移动,因此不会出现迭代器失效的情况

list的删除

  • list.clear(); /X移除容器的所有数据

  • list.erase(beg,end); //删除[beg,end)区间的数据,返回下一个数据的位置。

  • list.erase(pos); //删除pos位置的数据,返回下一个数据的位置。

  • lst.remove(elem); //删除容器中所有与elem值匹配的元素。

list的反序排列

  • lst.reverse(); //反转链表,比如lst包含1,3,5元素,运行此方法后,lst就包含5,3,1元素

Iist迭代器失效

  • 删除结点导致迭代器失效

删除即是将相应数据位置的元素地址释放掉,即返还给内部系统,在某些编译器中,该被释放的地址是可以进行访问并有明确复制(系统内部赋值),该系统地址是没有访问权限的,俗称野指针

示例:

cpp 复制代码
#include<iostream>
#include<list>
using namespace std;
int main() {
	list<int> lst = { 1,2,1,4,5 };
	list<int>::iterator it;
	for (it = lst.begin(); it != lst.end();) {
		if (*it == 1) {
			it = lst.erase(it);
		}
		else it++;
	}
	for (it = lst.begin(); it != lst.end(); it++) cout << *it<<' ';
}
相关推荐
jinyishu_5 分钟前
C++继承与多态进阶
开发语言·c++·程序人生
程序猿编码13 分钟前
用 C++ 从零写一个能训练的 GPT:标量自动微分 + Arena 内存池
开发语言·c++·gpt·transformer·模型推理
库玛西14 分钟前
快速幂算法全景总结图:从“愚公移山”到“细胞分裂”
c语言·c++·笔记·算法
小灰灰搞电子29 分钟前
Qt 队列容器 QQueue 的详解与示例
开发语言·qt·qqueue
小鬼头编程40 分钟前
信息学竞赛体系(CSP-J/S、NOIP、NOI、IOI)
c++·人工智能·青少年编程
ACP广源盛139246256731 小时前
GSV6155@ACP# Type-C 视频信号转换芯片:技术架构、工程痛点适配与落地场景分析
大数据·c语言·开发语言·人工智能·分布式·嵌入式硬件·架构
我不是懒洋洋1 小时前
从零实现一个分布式数据管道:dbt的核心设计
c++
程序员-Benothing1 小时前
Java集合:List实现类深度对比
java·开发语言·后端·面试·list
酷在前行1 小时前
【R论文复刻】Nature Communications 冲积图进阶:状态转移、流带排序与多面板排版(保姆级教程)
开发语言·r语言
Darkwanderor1 小时前
使用管道实现进程间通信 (IPC, Inter-Process Communitation)
linux·c语言·c++