C++-list
std::list
是C++标准模板库(STL)提供的双向链表容器,它提供了高效的插入和删除操作,特别适合频繁修改的序列。定义在 <list>
头文件中,属于 std
命名空间。该类的接口与常规容器接口基本一致。
模板原型:
cpp
template < class T, class Alloc = allocator<T> > class list;
allocator<T>:STL空间配置器(内存池)。
基本特性:
-
实现方式:双向链表结构,每个元素包含指向前驱和后继的指针。
-
内存分配:元素在内存中非连续存储的,通过指针链接。
-
泛型容器:通过模板实现,可以存储任何类型的元素。
-
迭代器:双向迭代器(支持++和--操作)。
1. 底层理解
list 底层是 带头双向循环链表。
cpp
template<typename T>
struct list_node{
T val;
list_node* prev;
list_node* next;
list_node(const T& data = T()) :val(data) , prev(nullptr) , next(nullptr) {}
};
template<typename T>
class list {
private:
list_node<T>* node;
}

2. 成员函数
2.1 成员类型
成员类型 | 解释 |
---|---|
value_type | 第一个模板参数(T) |
allocator_type | 第二个模板参数(Alloc) |
size_type | 无符号整数(size_t) |
reference | 类型引用(T&) |
const_reference | const类型引用(const T&) |
2.2 构造函数
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | explicit list (const allocator_type& alloc = allocator_type()) | 默认构造 |
2️⃣ | list (const list& x) | 拷贝构造 |
3️⃣ | explicit list (size_type n, const value_type& val = value_type(), const allocator_type& alloc = allocator_type()) | 使用 n 个 val 值初始化 |
4️⃣ | template <class InputIterator> list (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type()) | 使用一段迭代器区间初始化 |
2.3 赋值重载
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | list& operator= (const list& x) | 两个已存在的 list 对象的赋值 |
2.4 迭代器
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | iterator begin() | 返回指向 list 对象中第一个元素的迭代器 |
2️⃣ | const_iterator begin() const | 返回指向 list 对象中第一个元素的 const迭代器 |
3️⃣ | iterator end() | 返回指向 list 对象末尾元素之后位置的迭代器 |
4️⃣ | const_iterator end() const | 返回指向 list 对象末尾元素之后位置的 const迭代器 |
5️⃣ | reverse_iterator rbegin() | 返回指向 list 对象末尾元素的反向迭代器 |
6️⃣ | const_reverse_iterator rbegin() const | 返回指向 list 对象末尾元素的const反向迭代器 |
7️⃣ | reverse_iterator() rend() | 返回指向 list 对象起始元素之前位置的反向迭代器 |
8️⃣ | const_reverse_iterator() rend() const | 返回指向 list 对象起始元素之前位置的const反向迭代器 |

2.5 容量相关的接口
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | size_type size() const | 返回 list 对象中元素的数量 |
2️⃣ | bool empty() const | 判断当前 list 对象是否为空 |
2.6 元素的访问
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | reference front() | 返回 list 对象第一个元素的引用 |
2️⃣ | const_reference front() const | 返回 const list 对象第一个元素的 const引用 |
3️⃣ | reference back() | 返回 list 对象最后一个元素的引用 |
4️⃣ | const_reference back() const | 返回 const list 对象最后一个元素的引用 |
2.7 修改相关的接口
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | template <class InputIterator> void assign (InputIterator first, InputIterator last) | 使用一段迭代器区间赋值给 list 对象(通常使用其他容器) |
2️⃣ | void push_front (const value_type& val) | 在 list 对象头部插入 val 元素 |
3️⃣ | void pop_front() | 在 list 对象头部删除一个元素 |
4️⃣ | void push_back (const value_type& val) | 在 list 对象尾部插入 val 元素 |
5️⃣ | void pop_back() | 在 list 对象尾部删除一个元素 |
6️⃣ | iterator insert (iterator pos, const value_type& val); | 在 list 对象的 pos 位置迭代器插入 val 元素,返回新插入元素的迭代器 |
7️⃣ | iterator erase (iterator pos); | 删除 list 对象的 pos 位置迭代器元素,返回删除位置元素的下一个迭代器 |
8️⃣ | void clear(); | 清空 list 对象中所有元素 |
2.8 其他操作
序号 | 函数原型 | 说明 |
---|---|---|
1️⃣ | void reverse() | 逆置 list 对象中的元素 |
2️⃣ | void sort() | 排序 list 对象中的元素(默认升序) |
3️⃣ | void merge (list& x) | 合并两个有序的 list,将 x 对象中的所有元素合并到当前 list 中,合并完后 x 将变为空链表 |
4️⃣ | void unique() | 去重,但前提需要 list 对象有序 |
5️⃣ | void remove (const value_type& val) | 移除所有 val 元素 |
6️⃣ | void splice (iterator position, list& x) | 将x链表中的所有元素移动到当前链表的 position迭代器之前,移动后 x 变为空链表 |
7️⃣ | void splice (iterator position, list& x, iterator i) | 将x链表中 i 位置迭代器元素移动到当前链表的 position迭代器之前 |
8️⃣ | void splice (iterator position, list& x, iterator first, iterator last); | 将x链表一段迭代器区间移动到当前链表的 position迭代器之前 |
- reverse

- sort

- merge

- unique

- remove

6.splice

3. list迭代器失效
C++中,list 与 vector 迭代器失效有所不同,list迭代器失效主要发生在 元素被删除时
迭代器失效的情况:
-
erase 时被删除位置元素迭代器失效。
- 解决方式:通过 erase 返回值重新获取迭代器(erase返回删除元素的下一个位置迭代器)
-
整个 list 被销毁或赋值时,所有迭代器都会失效。
4. list模拟实现
cpp
// list.hpp
#pragma once
#include <iostream>
#include <cassert>
namespace simulate_list {
template<typename T>
struct list_node{
T val;
list_node* prev;
list_node* next;
list_node(const T& data = T()) :val(data) , prev(nullptr) , next(nullptr) {}
};
template<typename T , typename Ref , typename Ptr>
struct __list_iterator {
typedef list_node<T> node;
typedef __list_iterator<T , Ref , Ptr> self;
__list_iterator(node* nodeptr) :cur(nodeptr) {}
self& operator++() {
cur = cur->next;
return *this;
}
self operator++(int) {
self temp(cur);
cur = cur->next;
return temp;
}
self& operator--() {
cur = cur->prev;
return *this;
}
self operator--(int) {
self temp(cur);
cur = cur->prev;
return temp;
}
Ref operator*() {
return cur->val;
}
Ptr operator->() {
return &(operator*());
}
bool operator==(const self& s) {
return cur == s.cur;
}
bool operator!=(const self& s) {
return cur != s.cur;
}
node* cur;
};
template<typename T>
class list {
typedef list_node<T> node;
public:
typedef __list_iterator<T , T& , T*> iterator;
typedef __list_iterator<T , const T& , const T*> const_iterator;
iterator begin() { return iterator(head->next); }
iterator end() { return iterator(head); }
const_iterator begin() const { return const_iterator(head->next); }
const_iterator end() const { return const_iterator(head); }
bool empty() const { return head->next == head; }
T& front() { assert(!empty()); return head->next->val; }
T& back() { assert(!empty()); return head->prev->val; }
const T& front() const { assert(!empty()); return head->next->val; }
const T& back() const { assert(!empty()); return head->prev->val; }
size_t size() const {
size_t count = 0;
for (auto& a : *this) count++;
return count;
}
void clear() {
auto it = begin();
while (it != end())
it = erase(it);
}
void initializer_list() {
head = new node;
head->prev = head;
head->next = head;
}
list<T>() {
initializer_list();
}
list<T>(const list<T>& l) {
initializer_list();
for (auto& node : l)
push_back(node);
}
list<T>& operator=(list<T> l) {
std::swap(head , l.head);
return *this;
}
~list<T>() {
clear();
delete head;
head = nullptr;
}
iterator insert(iterator position , const T& val);
iterator erase(iterator position);
void push_front(const T& val) { insert(begin() , val); }
void pop_front() { assert(!empty()); erase(begin()); }
void push_back(const T& val) { insert(end() , val); }
void pop_back() { assert(!empty()); erase(--end()); }
private:
node* head = nullptr;
};
template<typename T>
typename list<T>::iterator list<T>::insert(list<T>::iterator position , const T& val) {
node* prev = position.cur->prev;
node* newnode = new node(val);
prev->next = newnode;
newnode->prev = prev;
newnode->next = position.cur;
position.cur->prev = newnode;
return iterator(newnode); // 返回新插入节点的迭代器
}
template<typename T>
typename list<T>::iterator list<T>::erase(list<T>::iterator position) {
node* prev = position.cur->prev;
node* next = position.cur->next;
prev->next = next;
next->prev = prev;
delete position.cur;
return iterator(next); // 返回删除元素的下一个元素
}
} // namespace simulate_list end