C++ STL list的使用
list简介
list是STL中的一个序列式容器,它的结构是一个双向带头循环循环链表,所以它任意位置插入和删除的效率很高,但是内存空间并不是连续的,所以不支持随机访问。
与之对应的还有forward_list,forward_list是单链表结构,只能向后迭代,而list支持双向迭代。
list的基本使用
要使用list及其方法,首先要引入头文件<list>
list的构造
构造函数 | 接口说明 |
---|---|
list() | 构造空的list |
list (size_type n, const value_type& val = value_type()) | 构造的list中包含n个值为val的元素 |
list (const list& x) | 拷贝构造函数 |
list (InputIterator first, InputIterator last) | 用[first, last)区间中的元素构造list |
#include<iostream>
#include<list>
using namespace std;
int main() {
//空构造
list<int> lt1;
//给定节点值进行构造
list<int> lt2{1,2,3};
//构造n个指定val值的链表
list<int> lt3(4,88);
//拷贝构造
list<int> lt4(lt2);
int ar[] = { 1,2,3,4,5};
int n= sizeof(ar) / sizeof(ar[0]);
//给定区间中的元素构造
list<int> lt5(ar, ar + n);
list<int> lt6(lt3.begin(), lt3.end());
return 0;
}
list iterator迭代器
这里的迭代器理解成一个指针,该指针指向list中的某个节点。
函数声明 | 接口类型 |
---|---|
begin() | 返回第一个元素的迭代器 |
end() | 返回最后一个元素下一个元素的迭代器 |
rbegin() | 返回第一个元素的reverse_iterator,即end位置 |
rend() | 返回最后一个元素下一个位置的reverse_iterator,即begin位置 |
注意:
- begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
- rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动
list的迭代打印
list有两种打印方式
- 一种是通过迭代器仿照数组的方式对迭代器进行++操作打印
- 一种是通过范围for直接对list进行打印
int main() {
list<int> lt1;
list<int> lt2{1,2,3};
list<int> lt3(4,88);
list<int> lt4(lt2);
int ar[] = { 1,2,3,4,5};
int n= sizeof(ar) / sizeof(ar[0]);
list<int> lt5(ar, ar + n);
list<int> lt6(lt3.begin(), lt3.end());
///
//定义迭代器对象it1为list第一个元素
list<int>::iterator it1 = lt5.begin();
//控制终止条件
while (it1 != lt5.end()) {
//对迭代器解引用输出迭代器指向元素的值
cout << *it1 << "->";
//输出完对迭代器++指向下一个元素
++it1;
}
cout << "end" << endl;
///
//通过auto自动推导出it2是一个反向迭代器类型
//反向迭代器打印出来和正向迭代器的顺序相反
auto it2 = lt5.rbegin();
while (it2 != lt5.rend()) {
cout << *it2 << "->";
//对反向迭代器的操作也是++,只不过这里++,指向的是前一个元素
++it2;
}
cout <<"end"<< endl;
//
//通过范围for对有有范围的数据进行迭代输出
for (auto &e : lt3) {
cout << e << "->";
}
cout << "end" << endl;
return 0;
}
list容量
函数声明 | 接口说明 |
---|---|
empty() | 检测list是否为空,是返回true,否则返回false |
size() | 返回list中有效节点的个数 |
list<int> lt1{ 1,2,3,4,5,6,7,8,9 };
list<int> lt2;
cout << lt1.empty() << endl;
cout << lt2.empty() << endl;
cout << lt1.size() << endl;
cout << lt2.size() << endl;
list元素访问
函数申明 | 接口说明 |
---|---|
front() | 返回list的第一个节点中值的引用 |
back() | 返回list最后一个节点中值的引用 |
list<int> lt1{ 1,2,3,4 };
list<int> lt2;
//输出lt1第一个节点元素的值
cout << lt1.front() << endl;
//cout << lt2.front() << endl;//这里lt2是一个空链表,所以不能对lt2的元素值进行访问,会造成奔溃
//输出lt1中最后一个节点元素的值
cout << lt1.back() << endl;
list增删查改
函数声明 | 接口说明 |
---|---|
push_back() | 尾插 |
push_front() | 头插 |
pop_back() | 尾删 |
pop_front() | 头删 |
insert() | 在pos位置插入值为val的元素 |
erase() | 删除pos位置的元素 |
swap() | 交换两个元素 |
clear() | 清空list中的有效元素 |
list<int> lt;
list<int> ltt{ 6,6,6,6,6,6,6 };
for (int i = 1; i <= 10; ++i) {
//循环尾插
lt.push_back(i);
}
show(lt);
//头插
lt.push_front(888);
show(lt);
//尾删
lt.pop_back();
show(lt);
//尾插
lt.push_back(666);
show(lt);
//指定位置插入
lt.insert(lt.end(), 888);
show(lt);
//删除指定位置元素
lt.erase(lt.begin());
show(lt);
//删除指定区间元素
lt.erase(lt.begin(), lt.end());
//交换两个链表元素
lt.swap(ltt);
show(ltt);
show(lt);
//清除链表中的元素
lt.clear();
show(lt);
show(ltt);
list算法操作
函数声明 | 接口说明 |
---|---|
remove() | 删除指定值的元素 |
reverse() | 反转链表 |
unique() | 去重 |
merge() | 合并两个有序链表 |
sort() | 链表排序 |
list<int> lt{ 4,3,5,7,98,4,76,1,6,6,6,6,6,8,9 };
list<int> ltt{ 1,2,4,5,7,99,654,99999};
//删除指定数据的元素
lt.remove(5);
show(lt);
//去重
lt.unique();
show(lt);
//反转链表
lt.reverse();
show(lt);
lt.sort();
show(lt);
//合并两个有序链表
lt.merge(ltt);
show(lt);
注意:
合并两个链表时要保证两个链表的有序,否则程序会崩溃