list
list,是用环状双向链表实现的。具体的的内存结构如下图:

其中需要解释的地方:1.end()指向的是一空白节点,用以实现STL前闭后开区间。2.前闭后开区间:在STL迭代器中,区间里要访问的元素一般采用[iterator1,iterator2)的表示方法。
一个list类中的数据成员是怎么样的呢?如下(g++,7.2.0)
list_node *next;
list_node *prev;
alignas(size_t) unsigned char _M_storage[sizeof(size_t)];//最终大小是一个size_t的大小,这个是用来,存储链表的大小。
在g++,7.2.0,win64下,sizeof(list) = 24。
list的构造、析构与赋值
构造函数
与vector,deque类似:
| 构造函数类型 | 函数原型 |
|---|---|
| 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()); |
| range (3) | template< class InputIterator> list (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()); |
| 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 il, const allocator_type& alloc = allocator_type()); |
赋值
使用等号赋值
| 类型 | 函数原型 |
|---|---|
| copy (1) | list& operator= (const list& x); |
| move (2) | list& operator= (list&& x) |
| initializer list (3) | list& operator= (initializer_list il)` |
使用assgin()赋值
| 类型 | 函数原型 |
|---|---|
| range (1) | template< class InputIterator> void assign (InputIterator first, InputIterator last); |
| fill (2) | void assign (size_type n, const value_type& val); |
| initializer list (3) | void assign (initializer_list il); |
元素访问
at,operator[]
此为非连续空间容器,C++并没有实现这种访问方式。
front,back
| Element access | 函数原型及说明 |
|---|---|
| front | access the first element (public member function) reference front(); const_reference front() const; |
| back | access the last element (public member function) reference back(); const_reference back() const; |
迭代器
list的迭代器tag为:a bidirectional iterator to value_type。它表示list是一个双向迭代器,另外,deque与vector的迭代器为,random access iterator随机访问迭代器,它同样为双向迭代器。但是随机访问迭代器。这样区别的目的,是因为他们能实现的一些具体操作不一样。如下:
list<int> a{1,2,3};
vector<int> b{1,2,3};
auto it1 = a.begin() + 2;//错误,list<int>(bidirectional iterator)迭代器不支持这种操作
auto it2 = b.begin() + 2;//正确,vector<int>(random access iterator)迭代器支持这种操作
所有支持的操作可以在相关页面进行查询。简而言之,随机访问迭代器就像是指针一样,重载了所有指针支持的运算符,而双向迭代器,并不支持有关的跨对象访问,只能沿着前后方向一个个访问。如下能获取到list正向或反向的迭代器。
| Iterators | |
|---|---|
| begin cbegin | returns an iterator to the beginning (public member function) iterator begin(); const_iterator begin() const; const_iterator cbegin() const;//c++11 |
| end cend | returns an iterator to the end (public member function) iterator begin(); const_iterator begin() const; const_iterator cbegin() const;//c++11 |
| rbegin crbegin | returns a reverse iterator to the beginning (public member function) reverse_iterator rbegin(); const_reverse_iterator rbegin() const; const_reverse_iterator crbegin() const;//c++11 |
| rend crend | returns a reverse iterator to the end (public member function) reverse_iterator rend(); const_reverse_iterator rend() const; const_reverse_iterator crend() const;//c++11 |
容量及其修改
容量
| Capacity | |
|---|---|
| empty | checks whether the container is empty (public member function) bool empty() const noexcept; |
| size | returns the number of elements (public member function) size_type size() const noexcept; |
| max_size | returns the maximum possible number of elements (public member function) size_type max_size() const noexcept; |
修改
| Modifiers | 函数原型及其说明 |
|---|---|
| clear | clears the contents (public member function)除end以外获取的迭代器均失效,它会让所有其他的元素析构,只留下一个end() void clear() noexcept; |
| insert | inserts elements (public member function),其返回的是指向新插入的第一个元素的迭代器,其插入的位置是,迭代器指向的元素的前面 single element (1) iterator insert (const_iterator position, const value_type& val); fill (2) iterator insert (const_iterator position, size_type n, const value_type& val); range (3) template iterator insert (const_iterator position, InputIterator first, InputIterator last); move (4) iterator insert (const_iterator position, value_type&& val); initializer list (5) iterator insert (const_iterator position, initializer_list<value_type> il); |
| emplace(C++11) | constructs element in-place (public member function),在指定位置用传入参数构造一个元素,并返回指向该元素的迭代器 template <class… Args> iterator emplace (const_iterator position, Args&&… args); |
| erase | erases elements (public member function),返回的是删除的最后的一个元素的后一个元素,若是最后一个便是指向end()的迭代器 iterator erase (const_iterator position); iterator erase (const_iterator first, const_iterator last); |
| push_back | adds an element to the end (public member function) void push_back (const value_type& val); void push_back (value_type&& val); |
| emplace_back(C++11) | constructs an element in-place at the end (public member function) template <class… Args> void emplace_back (Args&&… args); |
| pop_back | removes the last element (public member function) void pop_back(); |
| push_front | inserts an element to the beginning (public member function) void push_front (const value_type& val); void push_front (value_type&& val); |
| emplace_front(C++11) | constructs an element in-place at the beginning (public member function) template <class… Args> void emplace_front (Args&&… args); |
| pop_front | removes the first element (public member function) void pop_front(); |
| resize | changes the number of elements stored (public member function) void resize (size_type n); void resize (size_type n, const value_type& val); |
| swap | swaps the contents (public member function),与deque一样,无右值重载 void swap (list& x); |
操作
与vector,deque不大一样,list有它一些独有的操作。
注意:merge中的Compare comp,remove_if中的Predicate pred以及sort中的Compare comp,这些指一个函数指针或函数对象(或者叫仿函数----STL源码解析中的称呼,可以理解为一个重载了operator() 的类的对象。)
eg:
class Functor
{
public:
int operator()(int a, int b)
{
return a < b;
}
};
| Operations | |
|---|---|
| merge | merges two sorted lists (public member function),合并两个已经排好序的链表,否则就简单的合并链表,最终不会得到排好序的链表,再者,传入的x最终将无元素。 (1)void merge (list& x); void merge (list&& x); (2)template < class Compare> void merge (list& x, Compare comp); template < class Compare > void merge (list&& x, Compare comp); |
| splice | moves elements from another list (public member function)拼接两个链表 (1)entire list void splice (const_iterator position, list& x); void splice (const_iterator position, list&& x); (2)single element void splice (const_iterator position, list& x, const_iterator i); void splice (const_iterator position, list&& x, const_iterator i); (3)element range void splice (const_iterator position, list& x, const_iterator first, const_iterator last); void splice (const_iterator position, list&& x, const_iterator first, const_iterator last); |
| remove remove_if | removes elements satisfying specific criteria (public member function),移除满足特定条件的元素 void remove (const value_type& val); template < class Predicate> void remove_if (Predicate pred);//Predicate为仿函数,判断是否满足这个函数的条件 |
| reverse | reverses the order of the elements (public member function),反转链表。 void reverse() noexcept; |
| unique | removes consecutive duplicate elements (public member function),去重。binary_pred是去重的比较,第一个相等即重复第二个可以指定重复函数。 (1) void unique(); (2) template < class BinaryPredicate > void unique (BinaryPredicate binary_pred); |
| sort | sorts the elements (public member function)元素排序,第二个可以传入comp函数,来实现另类排序,比如绝对值小的。 (1) void sort(); (2)template < class Compare> void sort (Compare comp); |
本文深入探讨C++ STL中的list容器,详细讲解其内部结构、构造与析构、元素访问、迭代器特性、容量与修改操作,以及独有的操作如merge、splice、remove_if等,适合对C++数据结构有深入了解需求的读者。
1万+

被折叠的 条评论
为什么被折叠?



