C++ 标准库中的 std::list
是一个双向链表实现。std::list
是一个模板类,定义在 <list>
头文件中。它提供了一个双向链表的数据结构,用于在链表的两端进行快速插入和删除操作。
std::list
的主要特点
-
双向链表:
- 双向:每个节点都有指向前一个节点和下一个节点的指针,这使得在链表的任何位置都可以高效地插入或删除元素。
- 链表节点:链表中的每个节点存储一个数据元素以及两个指针(前向和后向指针)。
-
插入和删除操作:
- 高效插入/删除:在链表的任何位置(包括头部、尾部和中间)插入或删除元素的时间复杂度为常数时间(O(1)),前提是你已经得到了要插入或删除位置的迭代器。
- 不支持随机访问 :与
std::vector
和std::deque
不同,std::list
不支持直接通过索引访问元素。只能通过迭代器进行顺序访问。
-
迭代器:
- 双向迭代器 :
std::list
提供双向迭代器,允许你在链表中前向或后向遍历。
- 双向迭代器 :
-
不支持快速随机访问:
- 无法随机访问 :不像
std::vector
或std::deque
,std::list
不允许使用下标操作符访问元素。
- 无法随机访问 :不像
-
元素的稳定性:
- 稳定性:插入和删除操作不会改变链表中其他元素的地址。每个元素在链表中具有稳定的地址。
示例代码
以下是 std::list
的一些基本用法示例:
cpp
#include <iostream>
#include <list>
int main() {
// 创建一个 std::list 对象,元素为 int 类型
std::list<int> myList;
// 向列表中插入元素
myList.push_back(10); // 在尾部插入
myList.push_front(5); // 在头部插入
// 遍历列表并打印所有元素
std::cout << "List elements: ";
for (const auto& element : myList) {
std::cout << element << " ";
}
std::cout << std::endl;
// 插入元素到指定位置
auto it = myList.begin();
++it; // 指向第二个元素
myList.insert(it, 7); // 在第二个位置插入 7
// 删除元素
myList.remove(10); // 删除所有值为 10 的元素
// 打印所有元素
std::cout << "List after deletion: ";
for (const auto& element : myList) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
代码解释
-
创建列表:
std::list<int> myList;
创建一个int
类型的std::list
对象。
-
插入元素:
myList.push_back(10);
将 10 插入到列表的尾部。myList.push_front(5);
将 5 插入到列表的头部。
-
遍历和打印:
- 使用范围-based for 循环遍历
std::list
中的所有元素,并打印它们。
- 使用范围-based for 循环遍历
-
插入到指定位置:
auto it = myList.begin();
获取指向列表第一个元素的迭代器。myList.insert(it, 7);
在第二个位置插入元素 7。
-
删除元素:
myList.remove(10);
删除列表中所有值为 10 的元素。
-
打印所有元素:
- 再次遍历并打印列表中剩余的所有元素。
总结
std::list
是一个双向链表实现,提供高效的插入和删除操作,适用于需要频繁在链表中间进行插入或删除的场景。- 不支持:随机访问,不能通过下标操作符访问元素。
- 支持:双向迭代器,允许在链表中进行前向和后向遍历。