C++ STL list
list
list 是双向循环列表,使用需要先包含 <list>
头文件。
优点:
- 动态内存分配,不会造成内存浪费
- 可快速在任意位置插入或删除元素
缺点:
- 遍历速度比数组慢
- 需要额外的空间存储指针
构造函数
原型 | 描述 | |
---|---|---|
default (1) | list(); explicit list (const allocator_type& alloc); |
默认构造函数,返回空列表 |
fill (2) | explicit list (size_type n, const allocator_type& alloc = allocator_type()); list (size_type n, const value_type& val, const allocator_type& alloc = allocator_type()); |
使用 n 个 val 初始化(未指定 val 则使用对应类型的默认初始值) |
range (3) | template <class InputIterator> list (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); |
将 [first, last) 区间中的元素拷贝 |
copy (4) | list (const list& x); list (const list& x, const allocator_type& alloc); |
拷贝构造函数 |
move (5) | list (list&& x); list (list&& x, const allocator_type& alloc); |
|
initializer list (6) | list (initializer_list<value_type> il, const allocator_type& alloc = allocator_type()); |
示例:
// 打印 list
void printList(const list<int> lst) {
for (auto elem: lst) {
cout << elem << " ";
}
cout << endl;
}
// 测试构造函数
void testConstructor() {
// 默认构造函数,创建空链表
list<int> c1;
cout << "c1: ";
printList(c1);
// 创建包含 3 个元素的链表(元素默认值为 0)
list<int> c2(3);
cout << "c2: ";
printList(c2);
// 创建包含 5 个值为 2 的元素的链表
list<int> c3(5, 2);
cout << "c3: ";
printList(c3);
// 拷贝构造函数
list<int> c4(c3);
cout << "c4: ";
printList(c4);
// 将 [first, last) 区间中的元素拷贝
cout << "c5: ";
list<int> c5(c2.begin(), c2.end());
printList(c5);
}
输出:
c1:
c2: 0 0 0
c3: 2 2 2 2 2
c4: 2 2 2 2 2
c5: 0 0 0
赋值 =
| assign
函数 | 原型 | 描述 |
---|---|---|
operator= | list& operator=(const list& right); list& operator=(list&& right); |
将容器使用另一个容器替换 |
assign | void assign(size_type Count, const Type& Val); void assign(initializer_list<Type> IList); template <class InputIterator> void assign(InputIterator First, InputIterator Last); |
清除链表中的所有元素,并将新元素拷贝至目标链表。 |
示例:
// 测试赋值
void testAssignment() {
list<int> c1, c2;
c1.push_back(10);
c1.push_back(20);
c1.push_back(30);
c2.push_back(40);
c2.push_back(50);
c2.push_back(60);
cout << "初始 c1:" << endl;;
printList(c1);
// 使用 = 赋值
cout << "使用 = 赋值" << endl;
c1 = c2;
printList(c1);
// 指定区间赋值
c1.assign(++c2.begin(), c2.end());
cout << "指定区间赋值" << endl;
printList(c1);
// 指定元素值和个数赋值(7 个 4)
cout << "指定元素值和个数赋值(7 个 4)" << endl;
c1.assign(7, 4);
printList(c1);
// 使用待插入元素赋值
cout << "使用待插入元素赋值" << endl;
c1.assign({ 11, 22, 33, 44 });
printList(c1);
}
输出:
初始 c1:
10 20 30
使用 = 赋值
40 50 60
指定区间赋值
50 60
指定元素值和个数赋值(7 个 4)
4 4 4 4 4 4 4
使用待插入元素赋值
11 22 33 44
交换 swap
函数 | 原型 | 描述 |
---|---|---|
swap | void swap(list<Type, Allocator>& right); friend void swap(list<Type, Allocator>& left, list<Type, Allocator>& right) |
交换两个链表的元素。 |
示例:
// 测试 swap
void testSwap() {
list<int> c1({ 1, 2, 3 });
list<int> c2({ 7, 8, 9, 10 });
cout << "交换前 c1:" << endl;
printList(c1);
cout << "交换前 c2:" << endl;
printList(c2);
c1.swap(c2);
cout << "交换后 c1:" << endl;
printList(c1);
cout << "交换后 c2:" << endl;
printList(c2);
}
输出:
交换前 c1:
1 2 3
交换前 c2:
7 8 9 10
交换后 c1:
7 8 9 10
交换后 c2:
1 2 3
大小 size
| empty
| resize
函数 | 原型 | 描述 |
---|---|---|
size | size_type size() const; |
返回容器中元素个数 |
empty | bool empty() const; |
判断是否为空(true 为空) |
resize | void resize(size_type _Newsize); void resize(size_type _Newsize, Type val); |
为容器指定新大小 |
示例:
void testCapacity() {
list<int> c1;
// 判断 c1 是否为空
cout << "c1 是否为空:" << c1.empty() << endl;
// 重新指定大小(使用 10 填充)
c1.resize(5, 10);
cout << "resize 后的 c1:" << endl;
printList(c1);
// 查看大小
cout << "c1 的大小为:" << c1.size() << endl;
}
输出:
c1 是否为空:1
resize 后的 c1:
10 10 10 10 10
c1 的大小为:5
插入 push_back
| push_front
| emplace_back
| emplace_front
| insert
函数 | 原型 | 描述 |
---|---|---|
push_back | void push_back(const Type& val); void push_back(Type&& val); |
在容器尾部添加元素 |
push_front | void push_front(const Type& val); void push_front(Type&& val); |
在容器头部添加元素 |
emplace_back | void emplace_back(Type&& val); |
在容器尾部增加一个就地构造的元素 |
emplace_front | void emplace_front(Type&& val); |
在容器头部增加一个就地构造的元素 |
insert | iterator insert(iterator Where, const Type& Val); iterator insert(iterator Where, Type&& Val); void insert(iterator Where, size_type Count, const Type& Val); iterator insert(iterator Where, initializer_list<Type> IList); template <class InputIterator> void insert(iterator Where, InputIterator First, InputIterator Last); |
在容器的特点位置增加一个或多个或一个范围的元素 |
提示:
emplace_back()
和 push_back()
的区别,就在于底层实现的机制不同。push_back()
向容器尾部添加元素时,首先会创建这个元素,然后再将这个元素拷贝或者移动到容器中(如果是拷贝的话,事后会自行销毁先前创建的这个元素);而 emplace_back()
在实现时,则是直接在容器尾部创建这个元素,省去了拷贝或移动元素的过程。
删除 pop_back
| pop_front
| clear
| erase
| remove
函数 | 原型 | 描述 |
---|---|---|
pop_back | void pop_back(); |
删除容器尾部的元素 |
pop_front | void pop_front(); |
删除容器头部的元素 |
clear | void clear(); |
删除容器中的所有元素 |
erase | iterator erase(iterator Where); iterator erase(iterator first, iterator last); |
根据指定的位置或范围,删除一个或多个元素 |
remove | void remove(const Type& val); |
删除容器中所有匹配某个特定值的元素 |
索引 front
| back
函数 | 原型 | 描述 |
---|---|---|
front | reference front(); const_reference front() const; |
返回容器第一个元素的参考 |
back | reference back(); const_reference back() const; |
返回容器最后一个元素的参考 |
反转 reverse
函数 | 原型 | 描述 |
---|---|---|
reverse | void reverse(); |
反转容器中元素出现的顺序 |
示例:
// 测试反转
void testReverse() {
list<int> c1({ 1, 2, 3, 4, 5 });
cout << "反转前:" << endl;
printList(c1);
c1.reverse();
cout << "反转后:" << endl;
printList(c1);
}
输出:
反转前:
1 2 3 4 5
反转后:
5 4 3 2 1
排序 sort
示例:
// 测试排序
void testSort() {
list<int> c1({ 5, 9, 1, 4, 2, 0, 7, 8, 3, 6 });
cout << "排序前:" << endl;
printList(c1);
c1.sort();
cout << "排序后(升序):" << endl;
printList(c1);
c1.sort(greater<int>());
cout << "排序后(降序):" << endl;
printList(c1);
}
输出:
排序前:
5 9 1 4 2 0 7 8 3 6
排序后(升序):
0 1 2 3 4 5 6 7 8 9
排序后(降序):
9 8 7 6 5 4 3 2 1 0
提示:
不支持随机访问迭代器的容器,不可以使用标准的 sort
算法,但内部会提供对应的算法。
对自定义数据类型进行排序,需要向 sort
函数提供比较函数。