STL list基本用法

目录

list的底层实际是双向链表结构

list的使用

构造函数和赋值重载

构造函数 说明
list() 无参构造
list (size_type n, const value_type& val = value_type()) 构造的list中包含n个值为val的元素
list (const list& x) 拷贝构造函数
list (InputIterator first, InputIterator last) 用[first, last)区间中的元素构造list

构造函数和前面的容器用法相同

cpp 复制代码
void test1()
{
	list<int> lt1;//无参构造

	list<int> lt2(10, 1);//1,1,1,1,1,1,1,1,1,1

	list<int> lt3(lt2);//拷贝构造

	list<int> lt4(lt2.begin(), lt2.end());
}

赋值重载

cpp 复制代码
list& operator= (const list& x);
cpp 复制代码
void test1()
{
	list<int> lt1;//无参构造

	list<int> lt2(10, 1);//1,1,1,1,1,1,1,1,1,1

	list<int> lt3(lt2);//拷贝构造

	list<int> lt4(lt2.begin(), lt2.end());

	list<int> lt5;
	lt5 = lt4;//赋值重载
}

迭代器(最重要)

迭代器类型分为三种:单向迭代器、双向迭代器、随机迭代器

单向迭代器:支持++          例如forward_list、哈希的迭代器类型是单向迭代器

双向迭代器:支持++,- -      例如list、map、set的迭代器类型是双向迭代器

随机迭代器:支持++,- -,+,-   例如vector、string、deque的迭代器类型是随机迭代器

随机迭代器可以认为是特殊的双向迭代器,双向迭代器可以认为是特殊的单向迭代器

list的迭代器与vectorstring不同

迭代器的类型是与容器底层结构决定的

vectorstring的底层是连续的,所以它们的迭代器实际上就是指针,所以它们支持++,--,+,- ,类型是随机迭代器

list的底层是不连续的,前后是通过指针连接在一起的,所以它的迭代器不是指针(实际上是指针经过封装),经过封装后,迭代器会支持++、- -,类型是单向迭代器

对于不支持+,-,这样封装是因为:像it.begin()+5这样的效率太低,C++不支持

list的迭代器不支持像vector中的it.begin()+5,如果这样写会报错

只支持++,--

cpp 复制代码
void test2()
{
	list<int> lt{ 1,2,3,4,5,6 };
	lt.begin()--;
	lt.begin()++;
}

如果想将list的迭代器像vectorit.begin()+5一样移动多个位置,只能这样:

cpp 复制代码
void test2()
{
	list<int> lt{ 1,2,3,4,5,6 };
	list<int>::iterator it = lt.begin();
	for (size_t i = 0; i < 5; i++)
	{
		++it;
	}
}

剩下的,list迭代器也支持之前的函数,用法也相同


容量相关

empty

cpp 复制代码
bool empty() const;

判断容器是否为空

size

cpp 复制代码
size_type size() const;

返回容器中元素的个数


插入删除

list作为双向循环链表,头插,头删,尾插,尾删的效率都很高,所以list中都支持这些操作

函数 说明
void push_front (const value_type& val); 在list首元素前插入值为val的元素
void pop_front(); 删除list中第一个元素
void push_back (const value_type& val); 在list尾部插入值为val的元素
void pop_back(); 删除list中最后一个元素
cpp 复制代码
void test3()
{
	list<int> lt{ 1,2,3,4,5,6 };
	lt.push_back(10);
	lt.push_front(0);
	lt.pop_back();
	lt.pop_front();
}

insert

cpp 复制代码
iterator insert (iterator position, const value_type& val);

void insert (iterator position, size_type n, const value_type& val);
	
template <class InputIterator>
    void insert (iterator position, InputIterator first, InputIterator last);

insert的操作和vector中的用相同,但是这个insert不会导致迭代器失效

因为链表的插入必须要扩容,迭代器是指向某一个节点,插入后迭代器还是指向原先的节点,不会导致失效

erase

cpp 复制代码
iterator erase (iterator position);
iterator erase (iterator first, iterator last);

erase 的操作和vector中的用相同,这个erase 会导致迭代器失效

迭代器是指向某一个节点,删除这个节点后,迭代器失效


元素操作

reverse

cpp 复制代码
void reverse();

这个reverselist类中自带的一个函数,作用是逆置链表

<algorithm>中也有一个reverse函数
reverse函数中迭代器类型是双向迭代器,而list的迭代器类型就是双向迭代器,所以list也可以使用<algorithm>中的reverse

cpp 复制代码
void test4()
{
	list<int> lt{ 1,2,3,4,5,6 };
	lt.reverse();
	reverse(lt.begin(), lt.end());
}

sort

cpp 复制代码
void sort();

作用是排序,底层是归并
<algorithm>中也有sort函数,但是对于list来说,想要排序,只能使用list库中的sort函数,不能使用<algorithm>中也有sort

因为list的迭代器类型是双向迭代器,而<algorithm>中的sort的参数迭代器的类型是随机迭代器,所以list不能使用<algorithm>中的sort函数。

其实这里的sort意义不大,因为相对于<algorithm>中的sort效率低(list中的sort底层使用的是归并,<algorithm>中的sort使用的是快排)

而唯一的意义是:方便,数据量小了可以拍,但是数据量再大,就不要使用list中的sort

如果想要排序,完全可以把list中的数据拷贝到vector中,然后排vector,排序完之后再把数据拷贝会list

cpp 复制代码
void test5()
{
	list<int> lt{ 5,7,3,9,1,0,4,7,8,9,4, };
	vector<int> v;

	//将数据从list拷贝到vector
	for (auto e : lt)
	{
		v.push_back(e);
	}

	//在vector中排序
	reverse(v.begin(), v.end());

	//再把数据从vector拷贝到list中
	for (auto e : v)
	{
		lt.push_back(e);
	}
}

unique

cpp 复制代码
void unique();

作用是去重,但是需要先排序

cpp 复制代码
void test6()
{
	list<int> lt{2,6,5,2,2,2,2};
	lt.sort();
	lt.unique();// 5,6
}

remove

cpp 复制代码
void remove (const value_type& val);

remove的作用是先找到所有val的位置,然后erase掉所有的val

cpp 复制代码
void test6()
{
	list<int> lt{1,2,3,4,5,6,6,7,8};

	//移除元素6
	lt.remove(6);//1,2,3,4,5,7,8
}

splice

cpp 复制代码
void splice (iterator position, list& x);

void splice (iterator position, list& x, iterator i);
	
void splice (iterator position, list& x, iterator first, iterator last);

splice的作用是转移节点

  • void splice (iterator position, list& x),将x链表中的所有元素转移到position位置
  • void splice (iterator position, list& x, iterator i),将x链表中i位置的元素转移到position位置
  • void splice (iterator position, list& x, iterator first, iterator last),将x链表中[first,last)中的元素转移到position位置
cpp 复制代码
void test7()
{
	list<int> lt1{ 1,2,3,4,5,6,7 };
	list<int> lt2{ 0,0 };

	lt2.splice(++lt2.begin(), lt1);

	for (auto e : lt1)
	{
		cout << e << " ";
	}//lt1中的元素转移空了
	cout << endl;

	for (auto e : lt2)
	{
		cout << e << " ";
	}//0 1 2 3 4 5 6 7 0
	cout << endl;


	list<int> lt3{ 1,2,3,4,5,6,7 };
	list<int> lt4{ 0,0 };

	lt4.splice(++lt4.begin(), lt3, ++lt3.begin());
	for (auto e : lt3)
	{
		cout << e << " ";
	}//1 3 4 5 6 7
	cout << endl;

	for (auto e : lt4)
	{
		cout << e << " ";
	}//0 2 0
	cout << endl;


	list<int> lt5{ 1,2,3,4,5,6,7 };
	list<int> lt6{ 0,0 };

	lt6.splice(++lt6.begin(), lt5,++++lt5.begin(), --lt5.end());
	for (auto e : lt5)
	{
		cout << e << " ";
	}//1 2 7
	cout << endl;

	for (auto e : lt6)
	{
		cout << e << " ";
	}//0 3 4 5 6 0
	cout << endl;
}
相关推荐
Cao12345678932112 分钟前
简易学生成绩管理系统(C语言)
c语言·开发语言
The Future is mine14 分钟前
C# new Bitmap(32043, 32043, PixelFormat.Format32bppArgb)报错:参数无效,如何将图像分块化处理?
开发语言·c#
亿坊电商16 分钟前
PHP框架在微服务迁移中能发挥什么作用?
开发语言·微服务·php
烁34716 分钟前
每日一题(小白)模拟娱乐篇33
java·开发语言·算法
坐吃山猪35 分钟前
Python-Agent调用多个Server-FastAPI版本
开发语言·python·fastapi
88号技师37 分钟前
【1区SCI】Fusion entropy融合熵,多尺度,复合多尺度、时移多尺度、层次 + 故障识别、诊断-matlab代码
开发语言·机器学习·matlab·时序分析·故障诊断·信息熵·特征提取
软行1 小时前
LeetCode 每日一题 2845. 统计趣味子数组的数目
数据结构·c++·算法·leetcode
永远在Debug的小殿下1 小时前
查找函数【C++】
数据结构·算法
北漂老男孩1 小时前
Java对象转换的多种实现方式
java·开发语言
小贾要学习1 小时前
【C++】继承----下篇
android·java·c++