菜鸟笔记
提升您的技术认知

C++ 迭代器

阅读 : 46

迭代器就像用于访问容器元素的指针。

重要点:

迭代器用于从一个元素遍历到另一个元素,这一过程称为迭代容器。
迭代器的主要优点是为所有容器类型提供通用接口。
迭代器使算法独立于所使用的容器类型。
迭代器提供了一种浏览容器元素的通用方法。

语法

 :: iterator;
 :: const_iterator;

在迭代器上执行的操作:

运算符(*): : " *"运算符返回迭代器指向的当前位置的元素。
运算符(++): : " ++"运算符将迭代器加1、因此,迭代器指向容器的下一个元素。
运算符()和运算符(!=): : 这两个运算符都确定两个迭代器是否指向同一位置。
运算符(=): " ="运算符分配迭代器。

不同的黑白迭代器和指针

迭代器可以是智能指针,可以迭代复杂的数据结构。容器提供其迭代器类型。因此,我们可以说迭代器具有不同容器类型的公共接口。 容器类提供了两个基本成员函数,可用于迭代或遍历容器的元素:
begin(): begin()函数返回一个指向容器第一个元素的迭代器。
end(): end()函数返回一个指向容器的过去-最后一个元素的迭代器。
C++迭代器

让我们看一个简单的示例:

#include <iostream>
#include<iterator>
#include<vector>
using namespace std;
int main()
{
   std::vector<int> v{1,2,3,4,5};
   vector<int>::iterator itr;
   for(itr=v.begin();itr!=v.end();itr++)
   {
       std::cout << *itr <<" ";
   }
    return 0;
}

输出:

1 2 3 4 5

迭代器类别

可以通过以下方式对迭代器进行分类:
输入迭代器
输出迭代器
前向迭代器
双向迭代器
随机访问迭代器

C++迭代器

输入迭代器: 输入迭代器是用于访问容器中的元素,但它不会修改容器的值。 用于输入迭代器的运算符为:
增量运算符(++)
等号运算符()
不等于运算符(!=)
取消引用运算符(*) 输出迭代器: 输出迭代器是用于修改容器值的迭代器,但不会从容器中读取值。因此,我们可以说输出迭代器是仅写迭代器。 用于输出迭代器的运算符是:
增量运算符(++)
分配运算符(=) 转发迭代器: 转发迭代器是用于读取和写入容器的迭代器。这是一个多遍迭代器。 用于正向迭代器的运算符为:
增量运算符(++)
分配运算符(=)
等号运算符(=)
不等于运算符(!=) 双向迭代器: 双向迭代器是一种迭代器,它支持正向迭代器的所有功能,另外还增加了一个功能,即减量运算符(-)。我们可以通过减少迭代器来向后移动。 用于双向迭代器的运算符是:
增量运算符(++)
分配运算符(=)
等号运算符(=)
不等于运算符(!=)
减量运算符(-) 随机访问迭代器: 随机访问迭代器是一种迭代器,可在任意位置对元素进行随机访问。它具有双向迭代器的所有功能,另外还增加了一个功能,即指针添加和指针减法,以提供对元素的随机访问。

迭代器提供商

迭代器类别 提供者
输入迭代器 istream
输出迭代器 ostream
前向迭代器
双向迭代器 List, set, multiset, map, multimap
随机访问迭代器 Vector, deque, array

迭代器及其特征

迭代器 访问方法 运动方向 I/O功能
输入 线性 仅转发 只读
输出 线性 仅转发 只写
转发 线性 仅转发 读/写
双向 线性 前进和后退 读/写
随机 随机 前进和后退 读/写

迭代器的缺点

如果我们想同时从一种数据结构转移到另一种数据结构,则迭代器将无法工作。
如果我们要更新要迭代的结构,则迭代器由于其存储位置的方式而不允许我们这样做。
如果我们想在处理列表时回溯,则在这种情况下,迭代器将无法工作。

迭代器的优点

以下是迭代器的优点:
易于编程: 使用迭代器而不是使用下标运算符[]来访问容器的元素很方便。如果我们使用下标operator []访问元素,则需要跟踪运行时添加的元素数量,但是在迭代器的情况下不会发生这种情况。 让我们看一个简单的示例:

#include <iostream>
#include<vector>
#include<iterator>
using namespace std;
int main()
{
    vector<int> v{1,2,3,4,5};
    vector<int>::iterator itr;
    for(int i=0;i<5;i++)           // Traversal without using an iterator.
    {
        cout<<v[i]<<" ";
    }
    cout<<'\n';
    for(itr=v.begin();itr!=v.end();itr++)  // Traversal by using an iterator.
    {
        cout<<*itr<<" ";
    }
    v.push_back(10);
    cout<<'\n';
     for(int i=0;i<6;i++)
    {
        cout<<v[i]<<" ";
    }
    cout<<'\n';
     for(itr=v.begin();itr!=v.end();itr++)
    {
        cout<<*itr<<" ";
    }
     return 0;
}

输出:

      1 2 3 4 5                                                                                                          
      1 2 3 4 5                                                                                                          
      1 2 3 4 5 10                                                                                                       
      1 2 3 4 5 10 
在上面的示例中,我们观察到,如果在不使用迭代器的情况下遍历向量的元素,则需要跟踪容器中添加的元素数量。  

代码可重用性: 如果我们使用迭代器,则可以重用代码。在上面的示例中,如果我们用列表替换vector,则下标operator []将无法访问元素,因为列表不支持随机访问。但是,我们使用迭代器访问元素,然后也可以访问列表元素。
动态处理: : C++迭代器提供了动态添加或删除数据的功能。 让我们看一个简单的示例:

#include <iostream>
#include<vector>
#include<iterator>
using namespace std;
int main()
{
    vector<int> v{1,2,3,4,5};  // vector declaration
    vector<int>::iterator itr;
    v.insert(v.begin()+1,10);      
    for(itr=v.begin();itr!=v.end();itr++)
    {
        cout<<*itr<<" ";
    }
    return 0;
}

输出:

1 10 2 3 4 5
在上面的示例中,我们使用insert()函数在第二个位置插入一个新元素,而所有其他元素都移位了一个。  

差异b/w随机访问迭代器和其他迭代器

随机访问迭代器与其他迭代器之间最重要的区别是,随机访问迭代器需要'1'步骤来访问元素,而其他迭代器则需要'n'步骤。 
C++迭代器