前言:通过学习顺序表的玩法,我们已经知道关于迭代器遍历,及迭代器失效,那我们在C++中链表是如何玩的呢?
list
list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口。
list的构造
|list中的接口比较多,此处类似,只需要掌握如何正确的使用,然后再去深入研究背后的原理,已达到可扩展的能力。以下为list中一些常见的重要接口。
| 构造函数( (constructor)) | 接口说明 |
|---|---|
| list (size_type n, const value_type& val =value_type()) | 构造的list中包含n个值为val的元素 |
| list() | 构造空的list |
| list (const list& x) | 拷贝构造函数 |
| list (InputIterator first, InputIterator last) | 用[first, last)区间中的元素构造list |
list构造代码演示
cpp
#include <iostream>
#include <list>
#include <vector>
int main() {
// 1. 默认构造:构造空的 list
std::list<int> l1;
std::cout << "l1 size: " << l1.size() << "\n"; // 输出 0
// 2. 用 n 个相同值构造:包含 5 个值为 42 的元素
std::list<int> l2(5, 42);
std::cout << "l2 elements: ";
for (int x : l2) std::cout << x << " "; // 输出 42 42 42 42 42
std::cout << "\n";
// 3. 拷贝构造:从 l2 拷贝构造 l3
std::list<int> l3(l2);
std::cout << "l3 elements: ";
for (int x : l3) std::cout << x << " "; // 输出 42 42 42 42 42
std::cout << "\n";
// 4. 用迭代器区间构造:从 vector 的区间 [begin+1, end-1) 构造 list
std::vector<int> vec = {10, 20, 30, 40, 50};
std::list<int> l4(vec.begin() + 1, vec.end() - 1);
std::cout << "l4 elements: ";
for (int x : l4) std::cout << x << " "; // 输出 20 30 40
std::cout << "\n";
return 0;
}
list iterator的使用
此处,大家可暂时将迭代器理解成一个指针,该指针指向list中的某个节点。其实迭代器也分为好几种,分别是随机迭代器、双向迭代器,单向迭代器等。那他们的功能是什么呢?
如下图:
| 迭代器类型 | 核心能力 | 典型适用容器 |
|---|---|---|
| 输入迭代器 (Input) | 只读、单向(只能 ++)、只能遍历一次(读完就失效) | istream_iterator |
| 输出迭代器 (Output) | 只写、单向(只能 ++)、只能遍历一次(写完就失效) | ostream_iterator、inserter |
| 前向迭代器 (Forward) | 可读可写、单向(只能 ++)、可重复遍历(多次访问同一元素) | forward_list、unordered 容器 |
| 双向迭代器 (Bidirectional) | 可读可写、双向(++/--)、可重复遍历 | list、set、map |
| 随机访问迭代器 (Random Access) | 可读可写、双向、支持随机跳转(+/-/[]/ 比较距离) | vector、deque、array、string |
list迭代器接口
| 函数声明 | 接口说明 |
|---|---|
| begin()+end() | 返回第一个元素的迭代器+返回最后一个元素下一个位置的迭代器 |
| rbegin+ rend | 返回第一个元素的reverse_iterator,即end位置,返回最后一个元素下一个位置的reverse_iterator,即begin位置 |
cpp
#include <iostream>
#include <list>
int main() {
std::list<int> mylist = {10, 20, 30, 40, 50};
// 1. 正向遍历:使用 begin() 和 end()
std::cout << "正向遍历: ";
for (auto it = mylist.begin(); it != mylist.end(); ++it) {
std::cout << *it << " "; // 输出: 10 20 30 40 50
}
std::cout << "\n";
// 2. 反向遍历:使用 rbegin() 和 rend()
std::cout << "反向遍历: ";
for (auto it = mylist.rbegin(); it != mylist.rend(); ++it) {
std::cout << *it << " "; // 输出: 50 40 30 20 10
}
std::cout << "\n";
// 3. 演示反向迭代器的 ++ 行为
auto r_it = mylist.rbegin(); // 指向 50 (最后一个元素)
std::cout << "rbegin() 指向: " << *r_it << "\n"; // 50
++r_it; // ++ 操作让迭代器向前移动,指向 40
std::cout << "++r_it 指向: " << *r_it << "\n"; // 40
return 0;
}
- begin与end为正向迭代器,对迭代器执行++操作,迭代器向后移动
- rbegin(end)与rend(begin)为反向迭代器,对迭代器执行++操作,迭代器向前移动