list的介绍
list实际上就是一个带头双向循环链表
文档介绍
- list是可以在常数范围内在任意位置进行插入和删除的序列式容器,并且该容器可以前后双向迭代。
- list的底层是双向链表结构,双向链表中每个元素存储在互不相关的独立节点中,在节点中通过指针指向其前一个元素和后一个元素。
- list与forward_list非常相似:最主要的不同在于forward_list是单链表,只能朝前迭代,让其更简单高效。
- 与其他的序列式容器相比(array,vector,deque),list通常在任意位置进行插入、移除元素的执行效率更好。
- 与其他序列式容器相比,list和forward_list最大的缺陷是不支持任意位置的随机访问,比如:要访问list的第6个元素,必须从已知的位置(比如头部或者尾部)迭代到该位置,在这段位置上迭代需要线性的时间开销;list还需要一些额外的空间,以保存每个节点的相关联信息(对于存储类型较小元素的大list来说这可能是一个重要的因素)
list的使用
list的接口比较多,我们只需要掌握一些常用的接口即可。
list的构造函数
list的构造函数常用的是无参构造和拷贝构造
构造函数 | 函数说明 |
---|---|
list() | 无参构造,得到空的list |
list(const list& x) | 拷贝构造函数 |
list(size_type n, const value_type& val = value_type()) | 构造n个元素且数值为val的list |
list (InputIterator first, InputIterator last) | 使用迭代器构造list |
//常用无参构造和拷贝构造
void test2()
{
//1.默认构造,list() 得到空list
list<int> lt1;
lt1.push_back(1);
lt1.push_back(2);
lt1.push_back(3);
lt1.push_back(4);
//2.拷贝构造 list(const list& x)
list<int> lt2(lt1);
for (auto it : lt2)
{
cout << it << " ";
}
cout << endl;
//3.list(size_type n, const value_type& val = value_type())
list<int> lt3(10, 1);
for (auto it : lt3)
{
cout << it << " ";
}
cout << endl;
//4.list (InputIterator first, InputIterator last)
list<int> lt4(lt1.begin(), lt1.end());
for (auto it : lt4)
{
cout << it << " ";
}
cout << endl;
}
int main()
{
test2();
return 0;
}
上述构造方法,基本上和vector是一致的,只需要掌握住常用的两种构造方法即可
list iteraotr的使用
list支持正向和反向迭代器
begin+end:正向迭代器iteraotr,分别获取list的首元素地址和最后一个元素的下一个地址
rbegin+rend:反向迭代器reverse_iterator,分别获取list的最后一个元素的地址和首元素地址的前一个位置
void test3()
{
list<int> lt;
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
//begin+end 正向迭代器
list<int>::iterator it = lt.begin();
while (it != lt.end())
{
cout << *it << " ";
++it;
}
cout << endl;
//rbegin+rend 反向迭代器
list<int>::reverse_iterator rit = lt.rbegin();
while (rit != lt.rend())
{
cout << *rit << " ";
++rit;
}
cout << endl;
}
int main()
{
test3();
return 0;
}
注意:无论正向还是反向迭代器,都是++迭代器,且list不支持迭代器+n的操作(物理空间不连续)
list的常用函数
函数名 | 函数说明 |
---|---|
push_front | 头插 |
pop_front | 头删 |
push_back | 尾插 |
pop_back | 尾删 |
insert | 在pos位置插入数据val |
erase | 删除pos位置/迭代器区间的数据 |
swap | 交换链表(实际上就是交换两个list的成员变量的地址) |
clear | 清空链表(清空数据) |
empty | 判断list是否为空 |
size | 得到list元素个数 |
front | 得到list首元素 |
back | 得到list最后一个元素 |
resize | 更改size大小 |
熟悉掌握这些函数即可,其他函数可以在文档中查看
push和pop的函数
使用规则很简单,如下所示
void test4()
{
list<int> lt;
//1.push_back 尾插
lt.push_back(1);
lt.push_back(2);
lt.push_back(3);
lt.push_back(4);
for (auto it : lt)
{
cout << it << " ";
}
cout << endl;
//2.pop_back 尾删
lt.pop_back();
lt.pop_back();
for (auto it : lt)
{
cout << it << " "