【C++】STL容器--list的使用
目录
- 前言
- 一、list的介绍
- 二、list的使用
- 1. 构造函数和拷贝构造函数
- 2. 析构函数
- 3. 赋值运算符重载operator=
- 4. 迭代器begin/end、rbegin/rend
- 5. empty/size
- 6. front/back
- 7. assign
- 8. push_front/pop_front/push_back/pop_back
- 9. insert/erase
- 10. swap/clear
- 11.resize
- 12.reverse
- 13. sort
- 14. merge
- 15. unique
- 16. remove
- 17. splice
- 三、完整代码
前言
前面介绍了【C++】STL容器–vector的模拟实现详情请点击,本文将学习另一个STL容器–list,本文主要讲解list的使用
一、list的介绍
- list 是标准模板库(STL)中的一个容器,它实现了一个双向链表
- 支持在任意位置快速插入和删除元素,但不支持快速随机访问
二、list的使用
1. 构造函数和拷贝构造函数
- 构造函数有全缺省的构造,缺省值allocator_type()是空间配置器,避免频繁向堆上申请空间,提高效率,默认不传参即可
- 还可以使用n个值进行初始化
- 构造函数还可以使用迭代器进行初始化,迭代器可以是list类型也可以是其他类型
void test_list1()
{list<int> lt1;list<int> lt2(5, 4);list<int> lt3(lt2.begin(), lt2.end());vector<int> v(4, 7);list<int> lt4(v.begin() + 1, v.end() - 1);list<int> lt5(lt4);
}
2. 析构函数
析构函数在list生命周期结束后自动调用完成资源清理工作
3. 赋值运算符重载operator=
- 注意使用赋值运算符时,list对象已经创建,否则就会调用拷贝构造函数
void test_list2()
{list<int> lt1;list<int> lt2(5, 4);lt1 = lt2;
}
4. 迭代器begin/end、rbegin/rend
- begin/end、rbegin/rend都是获得开头或结尾位置的迭代器
void test_list3()
{int a[10] = { 1, 2, 3, 4, 5 };list<int> lt1(a, a+ 5);for (auto& e : lt1){cout << e << " ";}cout << endl;list<int>::iterator it = lt1.begin();while (it != lt1.end()){cout << *it << " ";++it;}cout << endl;list<int>::reverse_iterator it1 = lt1.rbegin();while (it1 != lt1.rend()){cout << *it1 << " ";++it1;}cout << endl;
}
5. empty/size
- empty:判断list是否为空
- size:返回有效数据个数
void test_list4()
{int a[10] = { 1, 2, 3, 4, 5 };list<int> lt1(a, a + 5);list<int>lt2;cout << lt1.empty() << endl;cout << lt1.size() << endl;cout << lt2.empty() << endl;cout << lt2.size() << endl;
}
6. front/back
front/back返回list第一个位置/最后一个位置数据的引用,可以访问和修改
7. assign
assin会将数据全部清空,再重新传入你需要的数据
void test_list5()
{int a[10] = { 1, 2, 3, 4, 5 };list<int> lt1(a, a + 5);list<int>lt2(3, 5);for (auto& e : lt2){cout << e << " ";}cout << endl;lt2.assign(lt1.begin(), lt1.end());for (auto& e : lt2){cout << e << " ";}cout << endl;}
8. push_front/pop_front/push_back/pop_back
push_front/pop_front/push_back/pop_back分别是头插、头删、尾插、尾删
void test_list6()
{list<int> lt1;lt1.push_front(1);lt1.push_front(2);lt1.push_front(3);lt1.push_front(4);lt1.push_front(5);lt1.pop_front();for (auto& e : lt1){cout << e << " ";}cout << endl;lt1.push_back(6);lt1.push_back(7);lt1.pop_back();for (auto& e : lt1){cout << e << " ";}cout << endl;
}
9. insert/erase
- list的insert不涉及迭代器失效问题,因为list的插入和删除是对链表节点做处理,并不会涉及异地扩容问题,但是erase会涉及迭代器失效问题,erase进行删除就是释放迭代器指向的节点,并改变节点之间的连接关系,节点被释放,那么再访问这个节点就会报错
- insert再迭代器位置插入一个值,并返回插入元素的迭代器;insert在迭代器位置插入n个值;insert在迭代器位置插入一段迭代区间
- insert在中间某个位置插入,需要使用循环迭代到那个位置再插入
- erase会返回一个迭代器,这个返回的迭代器是删除节点的下一个节点的迭代器,如果后续还要进行操作,可以接收这个返回值
void test_list7()
{int a[10] = { 1, 2, 3, 4, 5 };list<int> lt1(a, a + 5);list<int>::iterator it = lt1.begin();int ret = 1;while (ret--){it++;}lt1.insert(it, 8);for (auto& e : lt1){cout << e << " ";}cout << endl;list<int> lt2(a, a + 5);list<int>::iterator pos = lt2.begin();lt2.erase(pos);for (auto& e : lt2){cout << e << " ";}cout << endl;
}
10. swap/clear
- swap交换两个list对象数据
- clear清除list数据
11.resize
- resize用于改变list的有效数据个数,当n小于当前list有效数据个数,会删除多余节点数据,当小于有效数据个数,会在list后面尾插val
12.reverse
对list数据进行逆置操作
13. sort
- list的sort排序底层使用的是归并排序的非递归方式,虽然算法库中也有sort,但是它只支持随机访问的迭代器:vector、string等,不支持list双向迭代器排序
迭代器分为
- 单向迭代器:仅支持++/*
- 双向迭代器:支持++/–/*
- 随机访问迭代器:支持++/–/+/-/*/[]
- 数据量大时我们将数据存储在vector中进行排序,再copy到list中,这样比直接在list中排序效率更高
14. merge
- merge:将一个list对象 x 的数据归并到另一个list对象上(归并的前提是两个list对象数据必须是有序的)
- 归并后,x有效数据为0
void test_list10()
{int a[10] = { 1, 2, 3, 4, 5 };list<int> lt1(a, a + 5);list<int> lt2;lt2.push_back(3);lt2.push_back(1);lt2.push_back(4);lt2.push_back(5);lt1.sort();lt2.sort();lt2.merge(lt1);cout << lt1.size();cout << endl;for (auto& e : lt2){cout << e << " ";}
}
15. unique
- unique:去重操作
void test_list11()
{int a[10] = { 1, 1, 3, 4, 5, 5 };list<int> lt1(a, a + 6);for (auto& e : lt1){cout << e << " ";}cout << endl;lt1.unique();for (auto& e : lt1){cout << e << " ";}
}
16. remove
- remove:移除数据为val的节点
17. splice
- splice:将list对象x链接到另一个list对象上,x中链接的节点就不在x上了
- 将x全部节点连接到pos位置
- 将list对象x中迭代器i的节点链接到pos位置
- 将一个list对象x的某个迭代器区间的节点链接到pos位置
void test_list13()
{int a[10] = { 1, 1, 3, 4, 5, 5 };list<int> lt1(a, a + 6);list<int> lt2;lt2.push_back(7);lt2.push_back(12);lt2.push_back(1);lt2.push_back(3);lt1.splice(lt1.begin(), lt2, lt2.begin(), lt2.end());cout << lt2.size() << endl;for (auto& e : lt1){cout << e << " ";}cout << endl;
}
三、完整代码
完整代码点击查看