文章目录
一、头文件与基本概念
二、构造函数和析构函数
1.构造函数
2.析构函数
三、元素访问
front
back
四、迭代器相关函数
begin
end
rebegin(反向迭代器)
rend(反向迭代器)
五、容量相关函数
empty
size
max_size
六、修改器
assign
push_front
push_back
pop_front
pop_back
insert
erase
swap
clear
resize
七、操作
merge
splice
remove
remove_if
reserve
sort
unique
emplace函数(C++11及以上)
八、非成员函数重载
1.比较运算符重载(==、!=、<、<=、>、>=)
2.swap 函数(非成员函数重载)
C++ 的标准模板库(STL)中的 list
是一个功能强大且灵活的双向链表容器,它提供了众多接口函数来满足各种编程需求。在本篇博客中,我们将深入探讨 list
的所有成员函数,包括一些相对不太常用但在特定场景下非常有用的函数,我们这里只探讨基本的使用,不探讨底层原理,下一篇博客,我们将会模拟实现list。
一、头文件与基本概念
要使用list容器,首先需要包含<list>头文件,并引入std命名空间,使得我们可以直接使用list
而不是std::list。
#include <iostream>
#include <list>
using namespace std;
list
作为双向链表容器,其每个节点包含数据以及指向前一个节点和后一个节点的指针,这使得它在插入和删除操作上具有独特的优势,但在随机访问方面相对较弱。
二、构造函数和析构函数
1.构造函数
默认构造函数:创建一个空的list容器
list<int> myList1;
填充构造函数:构造一个含有n个val的某类型容器。
list<int> myList2(10, 2);
初始化列表构造函数:使用给定的初始化列表来初始化list
list<int> myList3 = { 1, 2, 3, 4, 5 };
拷贝构造函数:用另一个同类型的 list
容器来初始化新的 list
。
list<int> myList4(myList1);
范围构造函数:依据其他容器(如数组、vector
等)中指定范围的元素构建 list
。例如,假设有数组 int arr[] = {6, 7, 8, 9, 10};
list<int> myList4(arr, arr + 5);
移动构造函数(C++11及以上):允许将一个临时 list
资源转移到新创建的 list
中,以提高性能。例如:
list<int> createTempList()
{
list<int> temp = { 11, 12, 13 };
return temp;
}
list<int> myList6 = createTempList(); // 使用移动构造函数初始化 myList6
2.析构函数
当 list
容器对象超出作用域或被显式删除时,析构函数会自动被调用,释放链表中每个节点所占用的内存资源,确保内存不会泄漏。
三、元素访问
front
作用:返回list容器中的第一个元素
cout << "第一个元素: " << myList2.front() << endl;
back
作用:返回list容器中的最后一个元素
cout << "最后一个元素: " << myList2.back() << endl;
四、迭代器相关函数
begin
返回指向list容器中第一个元素的正向迭代器,通过这个迭代器可以顺序遍历容器中的元素
list<int>::iterator itBegin = myList2.begin();
end
返回指向list容器中最后一个元素之后位置的正向迭代器,用于标记整形遍历的结束。
list<int>::iterator itEnd = myList2.end();
rebegin(反向迭代器)
返回指向list容器中最后一个元素的反向迭代器,可用于从后向前遍历容器
list<int>::reverse_iterator itRBegin = myList2.rbegin();
rend(反向迭代器)
返回指向list容器中第一个元素之前位置的反向迭代器,标记反向遍历的结束。
list<int>::reverse_iterator itREnd = myList2.rend();
五、容量相关函数
empty
检查list容器是否为空,为空时返回true,否则返回false。
if (myList1.empty()) {
cout << "myList1 为空" << endl;
} else {
cout << "myList1 不为空" << endl;
}
size
返回list容器中当前元素的数量。
cout << "myList2 的元素个数: " << myList2.size() << endl;
max_size
返回list容器理论上能够容纳的最大元素数量,这个数量通常取决于系统资源和实现细节。
cout << "myList2 最大可容纳元素数: " << myList2.max_size() << endl;
六、修改器
assign
使用新的元素替换list容器中的所有现有元素。
myList2.assign(3, 100); // 将 myList2 中的元素替换为 3 个 100
也可以使用一个范围的元素来进行替换,假设存在另一个list: list<int> otherList = {200,300,400};
list<int> otherList = { 200,300,400 };
myList1.assign(otherList.begin(), otherList.end());
push_front
在list容器的头部插入一个新元素。
myList2.push_front(0);
push_back
在list容器的尾部插入一个新元素。
myList.push_back(6);
pop_front
移除 list
容器头部的元素。
myList2.pop_front();
pop_back
移除 list
容器尾部的元素
myList2.pop_back();
insert
在指定位置插入一个元素,列如,在myList2的第二个位置插入值为15的元素。
auto itInsertPos = myList2.begin();
++itInsertPos;
myList2.insert(itInsertPos, 15);
也可以一次性插入多个相同元素,如在myList的开头插入3个值为5的元素:
myList2.insert(myList2.begin(), 3, 5);
也可以插入一个范围的元素,假设有 vector<int> vec = {7,8,9}。
myList2.insert(myList2.end(), vec.begin(), vec.end());
erase
移除指定位置的元素。列如,移除myList2中的第三个元素。
auto itErasePos = myList2.begin();
++itErasePos;
++itErasePos;
myList2.erase(itErasePos);
也可以移除一个范围的元素,如移除myList2中的第二个元素到第四个元素(不包括第四个)。
auto start = myList2.begin();
++start;
auto end = start;
++end;
++end;
myList2.erase(start, end);
swap
交换两个 list容器的内容
list<int> listA = {1, 2, 3};
list<int> listB = {4, 5, 6};
listA.swap(listB);
clear
移除list容器中的所有元素,使其变为空容器
myList2.clear();
resize
两种情况:
- 当所给值大于当前的size时,将size扩大到该值,扩大的数据为第二个所给值,若未给出,则默认为容器所存储类型的默认构造函数所构造出来的值。
- 当所给值小于当前的size时,将size缩小到该值。
myList1.resize(10); // 将 myList1 大小调整为 10,新增元素使用默认值初始化
myList1.resize(5); // 将 myList1 大小调整为 5,移除后面的元素
myList1.resize(8, 20); // 将 myList1 大小调整为 8,新增元素值为 20
七、操作
merge
将另一个已排序的 list
合并到当前 list
中,合并后当前 list
仍保持有序。假设 list<int> listC = {1, 3, 5};
和 list<int> listD = {2, 4, 6};
,且 listC
和 listD
都已排序。
listC.merge(listD);
splice
将另一个list中的一个或多个元素移动到当前list的指定位置,列如,将 listD
的所有元素移动到 listC
的开头。
listC.splice(listC.begin(), listD);
也可以移动指定位置的单个元素,假设有 list<int> listE = {10,20,30}。
auto itE = listE.begin();
++itE;
listC.splice(listC.begin(), listE, itE);
remove
移除list容器中所有与指定值相等的元素
myList2.remove(2);
remove_if
根据指定的谓词(函数或函数对象)移除满足条件的元素。例如,移除所有偶数元素。
list<int> listG = { 1, 2, 3, 4, 5, 6 };
listG.remove_if([](int x) { return x % 2 == 0; });//去除偶数
reserve
反转list容器中元素的顺序
list<int> listH = {1, 2, 3, 4, 5};
listH.reverse();
sort
对 list
容器中的元素进行排序。默认按照升序排序,如果需要自定义排序规则,可以传入比较函数或函数对象。例如,按照降序排序,需要按照以下代码写。
list<int> listI = {5, 3, 4, 1, 2};
listI.sort(greater<int>());
unique
移除list容器中连续的重复元素,只保留一个。
list<int> listJ = {1, 1, 2, 2, 3, 3, 3, 4, 4};
listJ.unique();
emplace函数(C++11及以上)
在指定位置原地构造一个新元素,相比于 insert
函数,emplace
函数可以避免不必要的临时对象创建和复制,提高效率。例如,在 list
开头插入一个值为 100 的元素:
myList2.emplace(myList2.begin(), 100);
八、非成员函数重载
1.比较运算符重载(==
、!=
、<
、<=
、>
、>=
)
可以直接比较两个 list
容器是否相等或确定它们的大小关系,比较基于元素的逐对比较。例如:
list<int> listK = {1, 2, 3};
list<int> listL = {1, 2, 3};
if (listK == listL) {
cout << "listK 和 listL 相等" << endl;
}
2.swap
函数(非成员函数重载)
提供了一种更方便的方式来交换两个 list
容器的内容,与成员函数 swap
功能相同,但调用方式略有不同。
list<int> listM = {4, 5, 6};
list<int> listN = {7, 8, 9};
swap(listM, listN);
本篇博客到此结束,欢迎评论区留言~
本篇博客参考资料网址:cplusplus.com