C++STL之list(用法超详解)

C++STL之list

🌟🌟hello,各位读者大大们你们好呀🌟🌟

🚀🚀系列专栏:【C++的学习】

📝📝本篇内容:list基本介绍;构造函数;迭代器;空间成员函数;元素获取成员函数;元素操作成员函数;迭代器失效问题;list和vector的对比

⬆⬆⬆⬆上一篇:C++模拟实现string(图解+超详版)

💖💖作者简介:轩情吖,请多多指教(> •̀֊•́ ) ̖́-

1.list基本介绍

在STL中也有对list的实现,它是一个带头双向循环链表,底层是一个双向迭代器。forward_list是单链表,它底层只是一个单向迭代器。与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好 。但是他也有缺点,与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问 ,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息。

2.构造函数

list 构造函数
list 默认构造函数
list(size_type n, const value_type& val = value_type()) 构造n个值为val的元素
list (const list& x) 拷贝构造
list (InputIterator first, InputIterator last) 使用迭代器来构造
cpp 复制代码
#include <list>
#include <iostream>
using namespace std;
int main()
{
	//默认构造
	list<int> lt;

	//拷贝构造
	list<int> lt1(lt);

	//5个为20
	list<int> lt2(5, 20);
	for (auto& e : lt2)
	{
		cout << e << " ";
	}
	cout << endl;

	//使用迭代器构造
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	list<int> lt3(arr, arr + 10);
	for (auto& e : lt3)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

3.迭代器

list iterator/reverse_iterator
begin()+end() 双向迭代器
rbegin()+rend() 反向迭代器
cpp 复制代码
#include <list>
#include <iostream>
using namespace std;
int main()
{
	list<int> lt(5, 20);
	//迭代器
	list<int>::iterator it=lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}

	return 0;
}
cpp 复制代码
#include <list>
#include <iostream>
using namespace std;
int main()
{
	list<int> lt{ 1,2,3,3,4,5,6,7,8,9,10 };
	//反向迭代器
	list<int>::reverse_iterator rit = lt.rbegin();
	while (rit != lt.rend())
	{
		cout << *rit << " ";
		rit++;
	}

	return 0;
}

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

rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动

因为是双向迭代器,因此还可以使用- -

cpp 复制代码
#include <list>
#include <iostream>
using namespace std;
int main()
{
	list<int> lt={1,2,3,4,5,6,7,8,9,10};
	list<int>::iterator it = lt.end();
	while (it != lt.begin())
	{
		--it;//这边得先--再使用,因为end()指向的是最后一个元素的下一个
		cout <<*it << " ";
	}


	return 0;
}

4.空间成员函数

list 空间函数
size() 链表大小
empty() 链表是否为空
cpp 复制代码
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> lt{1, 2, 3, 4, 5, 6, 7};
	//大小
	cout << lt.size() << endl;
	//是否为空
	cout << lt.empty() << endl;

	return 0;
}

5.元素获取成员函数

list 元素获取函数
back() 获取最后一个元素的值
front() 获取第一个元素的值
cpp 复制代码
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> lt{1, 2, 3, 4, 5, 6, 7};
	cout << "The first element:";
	cout << lt.front() << endl;
	cout << "The end elemeent:";
	cout << lt.back() << endl;

	return 0;
}

6.元素操作成员函数

list 元素操作函数
push_back( (const value_type& val)) 尾插
push_front( (const value_type& val)) 头插
pop_front() 头删
pop_back() 尾删
iterator insert (iterator position, const value_type& val) 在positon位置插入val
void insert (iterator position, size_type n, const value_type& val) 在position位置插入n个val
iterator erase (iterator position) 删除position位置的元素
iterator erase (iterator first, iterator last) 以迭代器的方式删除[first,last)的元素
clear() 清空链表
swap(list& lt) 交换两个链表
cpp 复制代码
#include <iostream>
#include <list>
using namespace std;
int main()
{
	list<int> lt;
	//尾插
	lt.push_back(10);
	lt.push_back(11);
	lt.push_back(12);
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	//头插
	lt.push_front(9);
	lt.push_front(8);
	lt.push_front(7);
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	//头删
	lt.pop_front();
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	//尾删
	lt.pop_back();
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

再来看看插入和删除

cpp 复制代码
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
int main()
{
	list<int> lt;
	lt.push_back(10);
	lt.push_back(11);
	lt.push_back(12);
	lt.push_back(13);
	cout << "初始元素:";
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;
	
	//insert
	list<int>::iterator it=find(lt.begin(), lt.end(), 11);
	lt.insert(it, 7);
	cout << "insert之后:";
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	//erase(iterator position)
	auto it1 = find(lt.begin(), lt.end(), 12);
	lt.erase(it1);
	cout << "erase之后:";
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	//erase(iterator first,iterator last)
	lt.erase(lt.begin(), lt.end());
	cout << "insert之后:";
	for (auto& e : lt)
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

swap()和clear()

cpp 复制代码
#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);
	cout << "初始元素:";
	for (auto& e : lt)
	{
		cout << e<<" ";
	}
	cout << endl;

	//交换swap
	list<int> lt1;
	lt.swap(lt1);
	cout << "lt和默认构造lt1交换后的元素:";
	for (auto& e : lt)//没有元素
	{
		cout << e<<" ";
	}
	cout << endl;
	cout << "lt1的元素:";
	for (auto& e : lt1)
	{
		cout << e << " ";
	}
	cout << endl;

	//清空lt1
	lt1.clear();
	cout << "lt1清空元素后:";
	for (auto& e : lt1)//没有元素
	{
		cout << e << " ";
	}
	cout << endl;

	return 0;
}

7.迭代器失效问题

在前面咱们讲的vector时,我们也提到过迭代器失效问题,我们的list也会有这个问题,但是有区别。我们的list因为是一个个的结点,因此你进行插入的话并不会造成原来的迭代器失效,但是如果是删除呢?这就会有问题,因为当你删除一个结点时,肯定会释放空间,一旦释放空间,那么这个结点中的内容就已经无效了。当再次使用迭代器进行++时,就类似于访问野指针一样,导致崩溃。删除时的迭代器失效仅仅是被删除的迭代器,其他迭代器不会受任何影响。具体看我下一篇博客的list模拟实现中的迭代器实现可以更好的理解,list的迭代器是经过封装的,但本质还是结点

再来看一下下面的一个比较巧妙的用法

cpp 复制代码
#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);
	auto it = lt.begin();
	//一个个进行删除
	while (it!=lt.end())
	{
		//这边如果不用这种写法,就得接收返回值
		lt.erase(it++);//后置++是先使用后+1,因此在实现中,返回的其实是没有+1前的值,it迭代器已经+1了
		//it=lt.erase(it);
	}

	if (lt.empty())
	{
		cout << "list is empty"<<endl;
	}
	
	return 0;
}

8.list和vector的对比

🌸🌸C++STL之list的知识大概就讲到这里啦,博主后续会继续更新更多C++的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!你们的支持是博主坚持创作的动力!💪💪

相关推荐
桃子酱紫君17 分钟前
华为配置篇-BGP实验
开发语言·华为·php
QTX1873029 分钟前
JavaScript 中的原型链与继承
开发语言·javascript·原型模式
shaoing32 分钟前
MySQL 错误 报错:Table ‘performance_schema.session_variables’ Doesn’t Exist
java·开发语言·数据库
The Future is mine1 小时前
Python计算经纬度两点之间距离
开发语言·python
Enti7c1 小时前
HTML5和CSS3的一些特性
开发语言·css3
爱吃巧克力的程序媛1 小时前
在 Qt 创建项目时,Qt Quick Application (Compat) 和 Qt Quick Application
开发语言·qt
云 无 心 以 出 岫2 小时前
贪心算法QwQ
数据结构·c++·算法·贪心算法
独好紫罗兰2 小时前
洛谷题单3-P5719 【深基4.例3】分类平均-python-流程图重构
开发语言·python·算法
换一颗红豆2 小时前
【C++ 多态】—— 礼器九鼎,釉下乾坤,多态中的 “风水寻龙诀“
c++
篝火悟者2 小时前
自学-C语言-基础-数组、函数、指针、结构体和共同体、文件
c语言·开发语言