迭代器(Iterator)是一种对象,它可以用来遍历和访问容器中的元素,而不暴露容器的内部表示。迭代器提供了一种抽象的观点,使程序员能够以统一的方式处理各种不同类型的容器。
迭代器的特性:
1.
遍历性:迭代器可以依次访问容器中的所有元素。
2.
双向性:有些迭代器支持双向移动,即既可以向前移动,也可以向后移动。
3.
随机访问:某些迭代器支持随机访问,即能够直接访问容器中的任意元素。
迭代器的类型:
1.
输入迭代器(Input Iterator):只读,只能一次读入一个元素。支持遍历和双向移动。
- 解引用(dereference)操作:使用 `*it` 获取迭代器 `it` 指向的元素值。
- 后置自增(postincrement)操作:使用 `it++` 后移迭代器 `it` 并返回先前位置的值。
- 等值比较(equality-comparable)操作:可以使用 `it1 == it2` 和 `it1 != it2` 比较两个迭代器是否相等。
输入迭代器通常用于从序列中读取元素。在使用输入迭代器时,可以使用范围-for循环或者使用迭代器算法(比如`std::copy`)来遍历序列。
2.
输出迭代器(Output Iterator):只写,只能一次写入一个元素。支持遍历和双向移动。
输出迭代器是迭代器的一种类型,用于将数据写入到容器中。它只支持写操作,即每次只能写入一个元素,不能读取容器中的元素。输出迭代器通常用于算法中,如std::copy()函数,将一个容器中的元素复制到另一个容器中。
输出迭代器支持遍历容器中的元素,可以使用++运算符向前移动迭代器位置,支持双向移动。输出迭代器还可以用于追加数据到文件或网络输出流中。
C++ STL标准库中的一些容器和算法都支持输出迭代器,例如std::vector,std::list,std::set等容器,std::copy(),std::transform()等算法都可以使用输出迭代器。
3.
前向迭代器(Forward Iterator):可读写,只能一次读入一个元素。支持遍历、双向移动和随机访问。
前向迭代器是一种迭代器类型,支持遍历容器中的元素,它可以被遍历一次且只能向前移动,而且每个元素只能访问一次。前向迭代器可以执行读和写操作,并且支持双向移动。
在C++ STL标准库中,前向迭代器通常用于需要遍历容器但无需随机访问元素的算法中。例如,std::list容器只支持前向迭代器,因为它是一个链表,无法进行随机访问。
前向迭代器的用途很广泛,当我们需要对一个容器进行遍历并执行某些操作时,可以使用前向迭代器来实现。除了std::list之外,STL中的其他容器和算法也支持前向迭代器,例如std::forward_list,std::queue,std::stack等。
4.
双向迭代器(Bidirectional Iterator):可读写,可以一次读入一个元素。支持遍历、双向移动和随机访问。
双向迭代器是一种迭代器类型,它支持双向遍历容器中的元素,每个元素只能访问一次,也可以进行读和写操作。双向迭代器支持双向移动,它可以递增和递减,从而实现向前或向后移动一个位置。
在STL中,除了可以使用前向迭代器所支持的操作外,双向迭代器还支持--运算符(递减),因此它可以向前遍历容器中的元素。双向迭代器还可以用来实现某些算法,例如std::list容器和std::set容器。
双向迭代器比前向迭代器更加灵活,它提供了更多的迭代器操作,可以支持更多的算法和数据结构实现。同时,双向迭代器的随机访问性能也要比前向迭代器更好。但是,相比于随机访问迭代器,双向迭代器在元素访问和移动时的效率要稍低。
5.
随机访问迭代器(Random Access Iterator):可读写,可以一次读入一个元素。支持遍历、双向移动、随机访问。
随机访问迭代器是一种迭代器类型,它比双向迭代器更加灵活和强大,支持双向遍历容器中的元素,也支持任意位置的随机访问,是STL中最强大和最高效的迭代器类型。随机访问迭代器可以用于支持STL随机访问算法,例如sort()、binary_search()和lower_bound()等。
随机访问迭代器可以像指针一样进行算术运算,包括加法、减法、递增、递减等操作,因此它可以随机访问容器中的元素。另外,随机访问迭代器还可以使用[]操作符访问容器中的元素,支持迭代器之间的比较,以及其他STL迭代器所支持的操作,例如解引用、赋值、拷贝等。
在STL中,支持随机访问迭代器的容器有vector、deque和array等。需要注意的是,随机访问迭代器的功能强大,但也意味着它对容器实现的要求更高,因此不是所有的容器都可以提供随机访问迭代器。
迭代器的操作:
1.
初始化:使用容器的成员函数begin()和end()获取迭代器,或者使用++和--运算符移动迭代器。
2.
解引用:使用解引用运算符*访问迭代器指向的元素。
3.
比较:使用相等性运算符==和!=比较两个迭代器。
4.
算术运算:使用加法和减法运算符移动迭代器。
5.
赋值:使用赋值运算符=将一个迭代器赋值给另一个迭代器。
示例:
cpp
复制
#include
#include
int main() {
std::vector<int> v = {1, 2, 3, 4, 5};
std::vector<int>::iterator it = v.begin();
while (it != v.end()) {
std::cout << *it << std::endl;
++it;
}
return 0;
}
在这个例子中,我们使用了vector的迭代器遍历所有元素并输出。
#include
#include
int main() {
std::vector
// 使用正向迭代器遍历容器
for (std::vector
std::cout << *it << " ";
}
std::cout << std::endl;
// 使用反向迭代器遍历容器
for (std::vector
std::cout << *it << " ";
}
std::cout << std::endl;
return 0;
}
下面是一个使用迭代器操作map的例子,其中包括迭代器的遍历、插入和删除操作:
#include
#include
输出结果为:
第一次cout
1: apple
2: banana
3: orange
擦除后和插入后的第二次cout
1: apple
3: orange
4: grape