c++迭代器(Iterator)

迭代器(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 v = {1, 2, 3, 4, 5};

   

    // 使用正向迭代器遍历容器

    for (std::vector::iterator it = v.begin(); it != v.end(); ++it) {

        std::cout << *it << " ";

    }

    std::cout << std::endl;

    // 使用反向迭代器遍历容器

    for (std::vector::reverse_iterator it = v.rbegin(); it != v.rend(); ++it) {

        std::cout << *it << " ";

    }

    std::cout << std::endl;

    return 0;

}

下面是一个使用迭代器操作map的例子,其中包括迭代器的遍历、插入和删除操作:

 
  

#include 
#include 

int main() {
    std::map my_map {{1, "apple"}, {2, "banana"}, {3, "orange"}};

    // 遍历map
    for (auto iter = my_map.begin(); iter != my_map.end(); ++iter) {
        std::cout << iter->first << ": " << iter->second << std::endl;
    }

    // 插入元素
    my_map.insert({4, "grape"});

    // 删除元素
    auto iter = my_map.find(2);
    if (iter != my_map.end()) {
        my_map.erase(iter);
    }

    // 再次遍历map
    for (auto iter = my_map.begin(); iter != my_map.end(); ++iter) {
        std::cout << iter->first << ": " << iter->second << std::endl;
    }

    return 0;
}

输出结果为:

 
  

第一次cout
1: apple
2: banana
3: orange
擦除后和插入后的第二次cout
1: apple
3: orange
4: grape

你可能感兴趣的:(c++,算法)