list简介
1、list的插入和删除的时间复杂度是在常数范围内的序列式容器,并且由于list的底层是用双链表实现的,该容器支持双向迭代。 2、与其他序列式容器相比(array,vector,deque),list在任意位置进行插入和删除的效率更高。 3、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) | 使用迭代器构造 |
list的迭代器
在vector中,由于vector的底层是用连续空间进行存储的,因此原生指针就可以作为迭代器使用;但是list的底层是非连续空间,原生指针无法再作为迭代器,因此list的迭代器是通过模板封装实现的,这部分的底层原理放在下一篇博客模拟实现时进行详细解释。
迭代器 | 接口说明 |
---|
begin() + end() | 返回第一个元素的迭代器和返回最后一个元素的迭代器 | rbegin() + rend() | 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置 |
从图中可以看出,begin()是指向头节点的下一个节点,end()是指向头节点的。
list的capacity
capacity | 接口说明 |
---|
capacity() | 检测list是否为空,是返回true,否则返回false | size() | 返回list中的有效节点个数 |
由于list的空间不是连续的,在使用时即插即用,因此list的底层没有改变空间和改变有效长度的函数reserve和resize。
list的元素提取
element access | 接口说明 |
---|
front() | 返回list中第一个节点中的值 | back() | 返回list中最后一个节点中的值 |
list的插入和删除
插入删除 | 接口说明 |
---|
push_front | 在list的第一个元素之前插入 | pop_front | 删除list中的第一个元素 | push_back | 在list的最后一个元素之后插入 | pop_back | 删除list中的最后一个元素 | insert | 在list的pos位置插入 | erase | 删除list的pos位置的元素 | clear | 清除list中的有效元素 |
list<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
v1.push_back(4);
v1.push_back(5);
v1.push_back(6);
cout << "push_back(): ";
for(auto e : v1)
cout << e << " ";
cout << endl;
v1.push_front(10);
v1.push_front(12);
v1.push_front(13);
cout << "push_front(): ";
for(auto e : v1)
cout << e << " ";
cout << endl;
v1.pop_back();
v1.pop_back();
cout << "pop_back(): ";
for(auto e : v1)
cout << e << " ";
cout << endl;
v1.pop_front();
v1.pop_front();
cout << "pop_front(): ";
for(auto e : v1)
cout << e << " ";
cout << endl;
list<int>::iterator pos = find(v1.begin(), v1.end(), 3);
v1.insert(pos, 100);
cout << "insert(): ";
for(auto e : v1)
cout << e << " ";
cout << endl;
pos = find(v1.begin(), v1.end(), 4);
v1.erase(pos);
cout << "erase(): ";
for(auto e : v1)
cout << e << " ";
cout << endl;
list的迭代器失效
在前面的stl容器中已经介绍过了迭代器失效的问题,这里的迭代器可以理解为指针,迭代器失效指的是迭代器所指向的节点无效,即该节点所指向的空间被释放了或者已经无意义了,如果此时还在该节点的迭代器进行操作就会出现错误。list的底层是带头节点的双向循环链表,因此在list中进行插入的时候不会导致迭代器的失效,只有在删除的时候才会失效,因为list的删除是释放该节点,此时对应的迭代器指向的空间是无效的。 这里还要注意一点,失效的只是被删除节点的迭代器,不会影响其他节点的迭代器。
例如上面这段代码,目的是像想删除list中的所有元素,但是在删除之前没有保留当前元素的下一个节点的位置,在删除之后进行加一就会导致野指针的访问,这是典型的迭代器失效。 因此想要防止迭代器失效,就需要在删除节点之前,将该节点的下一个位置保存下来,及时更新迭代器。
|