零.前言

学习了vector与string我们可以知道,所谓的STL就是将字符串,数组等数据结构进行严密地封装,方便我们直接使用而不需要进行临时创建,本节将介绍STL中的list,该类是对双向带头循环链表的使用。

1.list的介绍

list表示的是一个双向带头循环链表,允许在常数范围内的任意位置进行插入和删除,且前后可以进行双向迭代。其缺陷和链表一样就是不能支持随机访问(下标访问),但是在任意位置进行插入的效率更高。

2.创建变量

在创建变量之前别忘记包含list的头文件。

	list<int> l1;//创建一个空对象
	list<int> l2(3, 1);//创建一个包含3个1的对象
	list<int> l3(l2);//拷贝构造
	list<int> l4(l3.begin()++, l3.end()--);//在l3.begin()与l3.end()之间创造对象

注意由于l3是链表,因此不能将l3.begin()进行+1等操作。但是可以进行++,–的操作

3.遍历

与list和vector不同,list的遍历不能使用下标遍历,因为他是链表。
但我们可以使用迭代器进行遍历,这里的迭代器是双向迭代器,而不是像list和vector一样是随机迭代器。
双向迭代器的构造使其可以进行++等访问操作,在底层实际上就是操作符重载。

(1)迭代器遍历

	list<int>::iterator it = l3.begin();
	while (it != l3.end())
	{
		*it += 1;
		cout << *it<<" ";
		it++;
	}

同时也支持rbegin与rend,这里不予演示了。

(2)范围for遍历

	for (auto& e : l3)
	{
		cout << e << " ";
	}

使用范围for时,其底层也是迭代器,像vector一样传链表名即可。将迭代器类型改为reverse_iterator即可使用反向迭代器。反向迭代器在string详解中已经介绍过了。

4.list的大小

链表是插入元素,不需要进行提前扩容,因此没有reserve操作。我们可以使用empty来判空,使用size返回大小。

	cout << l1.empty() << endl;
	cout << l3.size() << endl;

在这里插入图片描述

5.插入删除

(1)头尾插删

我们可以使用push_back,push_front,pop_back,pop_front等进行插入和删除。

	l1.push_back(1);
	l1.push_back(2);
	l1.push_back(5);
	l1.push_back(3);
	l1.push_back(4);
	l1.push_front(6);
	l1.push_front(8);
	l1.pop_front();
	l1.pop_back();
	for (auto& e : l1)
	{
		cout << e << " ";
	}

在这里插入图片描述

(2)insert与erase

insert使用:

	auto pos = ++l1.begin();
	l1.insert(pos, 5);//在pos位置前加1个5
	l1.insert(pos, 3, 5);//在pos位置前加3个5
	l1.insert(pos, l3.begin(), l3.end());//将l3加到pos位置前
	for (auto& e : l1)
	{
		cout << e << " ";
	}
	

erase使用:

	l1.erase(pos);//删除pos位置元素
	l1.erase(++l1.begin(), --l1.end());//删除中间内容

在使用erase时要注意迭代器失效问题(迭代器指向节点被删除)。
在这里插入图片描述

6.交换,排序与清除

(1)排序

在vector中我们可以使用algorithm中的sort进行排序,而在list中只能使用list提供的sort,这是因为算法中的sort传参只能传随机迭代器,而list中是双向迭代器。
我们拿上方代码没erase的时候进行排序:

	l1.sort();
	for (auto& e : l1)
	{
		cout << e << " ";
	}

在这里插入图片描述
链表的排序效率过低,如果要排序尽量使用vector不要使用list。

(2)交换

将两个链表中内容进行交换的函数:

	l1.swap(l3);

在这里插入图片描述

(3)清除

清空链表中元素。

l1.clear();

在这里插入图片描述

7.总结

list的使用与vector基本一致,但是底层的实现却大相径庭,要真正理解list我们还需要多去阅读STL的源代码,可以尝试着模拟实现一下list类。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐