STL 迭代器(iterator)详解

Posted linuxandmcu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了STL 迭代器(iterator)详解相关的知识,希望对你有一定的参考价值。

背景:指针可以用来遍历存储空间连续的数据结构,但是对于存储空间非连续的,就需要寻找一个行为类似指针的类,来对非数组的数据结构进行遍历。因此,我们引入迭代器概念。

?

一、迭代器(iterator)介绍

迭代器(Iterator)是一种检查容器内元素并遍历元素的数据类型。迭代器是指针的泛化,它允许程序员用相同的方式处理不同的数据结构(容器)。

迭代器的功能

共有五种迭代器,各个迭代器的功能如下:

迭代器类别 说明
输入 从容器中读取元素。输入迭代器只能一次读入一个元素向前移动,输入迭代器只支持一遍算法,同一个输入迭代器不能两遍遍历一个序列
输出 向容器中写入元素。输出迭代器只能一次一个元素向前移动。输出迭代器只支持一遍算法,统一输出迭代器不能两次遍历一个序列
正向 组合输入迭代器和输出迭代器的功能,并保留在容器中的位置
双向 组合正向迭代器和逆向迭代器的功能,支持多遍算法
随机存取 组合双向迭代器的功能与直接访问容器中任何元素的功能,即可向前向后跳过任意个元素

迭代器的操作

能够让迭代器与算法不干扰的相互发展,最后又能无间隙的粘合起来。重载了*,++,==,!=,=运算符,用以操作复杂的数据结构。容器提供迭代器,算法使用迭代器。

每种迭代器均可进行包括表中前一种迭代器可进行的操作。

迭代器操作 说明
所有迭代器
p++ 后置自增迭代器
++p 前置自增迭代器
输入迭代器
*p 复引用迭代器,作为右值
p=p1 将一个迭代器赋给另一个迭代器
p==p1 比较迭代器的相等性
p!=p1 比较迭代器的不等性
输出迭代器
*p 复引用迭代器,作为左值
p=p1 将一个迭代器赋给另一个迭代器
正向迭代器 提供输入输出迭代器的所有功能
双向迭代器
--p 前置自减迭代器
p-- 后置自减迭代器
随机存取迭代器
p+=i 将迭代器递增i位
p-=i 将迭代器递减i位
p+i 在p位加i位后的迭代器
p-i 在p位减i位后的迭代器
p[i] 返回p位元素偏离i位的元素引用
p<p1 如果迭代器p的位置在p1前,返回true,否则返回false
p<=p1 p的位置在p1的前面或同一位置时返回true,否则返回false
p>p1 如果迭代器p的位置在p1后,返回true,否则返回false
p>=p1 p的位置在p1的后面或同一位置时返回true,否则返回false

各容器支持迭代器的类别

每种容器类型都定义了自己的迭代器类型,如vector:vector< int>:: iterator iter; //定义一个名为iter的变量,数据类型是由vector< int>定义的iterator 类型。常用迭代器类型如下:

容器 支持的迭代器类别 说明
vector 随机访问 一种随机访问的数组类型,提供了对数组元素进行快速随机访问以及在序列尾部进行快速的插入和删除操作的功能。可以再需要的时候修改其自身的大小
deque 随机访问 一种随机访问的数组类型,提供了序列两端快速进行插入和删除操作的功能。可以再需要的时候修改其自身的大小
list 双向 一种不支持随机访问的数组类型,插入和删除所花费的时间是固定的,与位置无关。
set 双向 一种随机存取的容器,其关键字和数据元素是同一个值。所有元素都必须具有惟一值。
multiset 双向 一种随机存取的容器,其关键字和数据元素是同一个值。可以包含重复的元素。
map 双向 一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个特定的关键字只能与一个元素关联。
multimap 双向 一种包含成对数值的容器,一个值是实际数据值,另一个是用来寻找数据的关键字。一个关键字可以与多个数据元素关联。
stack 不支持 适配器容器类型,用vector,deque或list对象创建了一个先进后出容器
queue 不支持 适配器容器类型,用deque或list对象创建了一个先进先出容器
priority_queue 不支持 适配器容器类型,用vector或deque对象创建了一个排序队列

如上表所示,迭代器类型主要支持两类,随机访问和双向访问。其中vector和deque支持随机访问,list,set,map等支持双向访问。


二、容器迭代器的使用

下面列举了些例子说明各个容器的用法:

1、vector

#include "stdafx.h"
#include <iostream>
#include <vector>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the vector
    vector<int> vecTemp;
    for (int i = 0; i<6; i++)
    {
        vecTemp.push_back(i);
    }

    // Display contents of vector
    cout <<"Original deque: ";    
    vector<int>::iterator it;
    for (it = vecTemp.begin(); it!=vecTemp.end(); it++)
    {
        cout <<*it <<" ";
    }

    return 0;
}

/*
输出结果:
Original deque: 0 1 2 3 4 5
*/

2、deque

#include "stdafx.h"
#include <iostream>
#include <deque>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the deque
    deque<int> dequeTemp;
    for (int i = 0; i<6; i++)
    {
        dequeTemp.push_back(i);
    }

    // Display contents of deque
    cout <<"Original deque: ";
    deque<int>::iterator it;
    for (it = dequeTemp.begin(); it != dequeTemp.end(); it++)
    {
        cout <<*it <<" ";
    }
    cout <<endl;

    return 0;
}
/*
输出结果:
Original deque: 0 1 2 3 4 5
*/

3、list

#include "stdafx.h"
#include <iostream>
#include <list>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the list
    list<int> listTemp;
    for (int i = 0; i<6; i++)
    {
        listTemp.push_back(i);
    }

    // Display contents of list
    cout << "Original list: ";
    list<int>::iterator it;
    for (it = listTemp.begin(); it != listTemp.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    // Insert five 9 into the list
    list<int>::iterator itStart = listTemp.begin();
    listTemp.insert(itStart,5,9);

    // Display the result
    cout << "Result of list: ";
    for (it = listTemp.begin(); it != listTemp.end(); it++)
    {
        cout << *it << " ";
    }
    cout << endl;

    return 0;
}
/*
输出结果:
Original list: 0 1 2 3 4 5
Result of list: 9 9 9 9 9 0 1 2 3 4 5
*/

4、set

#include "stdafx.h"
#include <iostream>
#include <set>

using namespace std;

int main(int argc, char* argv[])
{
    // Create and populate the set
    set<char> setTemp;
    for (int i = 0; i<6; i++)
    {
        setTemp.insert('F'-i);
    }

    // Display contents of set
    cout <<"Original set: ";
    set<char>::iterator it;
    for (it = setTemp.begin(); it != setTemp.end(); it++)
    {
        cout <<*it <<" ";
    }
    cout <<endl;

    return 0;
}
/*
输出结果:
Original set: A B C D E F
*/

5、map

#include "stdafx.h"
#include <iostream>
#include <map>

using namespace std;

typedef map<int, char> MyMap;

int main(int argc, char* argv[])
{
    // Create and populate the map
    MyMap mapTemp;
    for (int i = 0; i<6; i++)
    {
        mapTemp[i] = ('F'-i);
    }

    // Display contents of map
    cout <<"Original map: " <<endl;
    MyMap::iterator it;
    for (it = mapTemp.begin(); it != mapTemp.end(); it++)
    {
        cout << (*it).first << " --> ";
        cout << (*it).second << std::endl;
    }
    cout <<endl;

    return 0;
}
/*
输出结果:
Original map:
0 --> F
1 --> E
2 --> D
3 --> C
4 --> B
5 --> A
*/

以上是关于STL 迭代器(iterator)详解的主要内容,如果未能解决你的问题,请参考以下文章

STL之迭代器(iterator)

STL 笔记 迭代器 iterator

STL源码分析--iterator

Sword STL迭代器prev,next相关函数

STL源码分析-iterator(迭代器)

SGI-STL简记-迭代器解析