1、迭代器概述
迭代器的特点:
- 用于指向顺序容器和关联容器中的元素
- 迭代器用法和指针类似
- 有const 和非 const两种
- 通过迭代器可以读取它指向的元素
- 通过非const迭代器还能修改其指向的元素
总结: 有了迭代器就可以访问容器类对象中的元素了。
2、迭代器的种类
- 双向迭代器
- 随机访问迭代器
注意:不同的迭代器上面支持的操作不同。
3、定义和使用迭代器
(1)定义迭代器
迭代器是针对容器类的,我们需要在某个容器上定义一个迭代器。通过迭代器,可以访问容器类对象中的元素。
//定义非const迭代器
容器类名::iterator 变量名;
//定义const迭代器
容器类名::const_iterator 变量名;
(2)使用迭代器访问元素
* 迭代器变量名 = xxx;//与指针很类似
(3)普通迭代器上的基础操作
迭代器上可以执行 ++
操作, 以使其指向容器中的下一个元素。如果迭代器到达了容器中的最后一个元素的后面,此时再使用它,就会出错,类似于使用NULL或未初始化的指针一样。
4、迭代器应用举例
#include <vector>
#include <iostream>
using namespace std;
int main() {
vector<int> v; //一个存放int元素的数组(容器),一开始里面没有元素的空数组
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);//向数组中添加元素1234
vector<int>::const_iterator i; //常量迭代器,只能访问,不能修改。
for( i = v.begin();i != v.end();++i )// v.rbegin()会返回一个指向最后一个元素的反向迭代器,赋值给i,迭代器i指向的元素在不断变化,直到指向最后一个元素后一个位置。
cout << * i << ",";
cout << endl;
vector<int>::reverse_iterator r; //反向迭代器,与普通迭代器不兼容
for( r = v.rbegin();r != v.rend();r++ )//v.rbegin()会返回一个指向最后一个元素的反向迭代器,赋值给i。执行 ++ 时指向的元素前移一个。
cout << * r << ",";
cout << endl;
vector<int>::iterator j; //非常量迭代器
for( j = v.begin();j != v.end();j ++ )
* j = 100;
for( i = v.begin();i != v.end();i++ )
cout << * i << ",";
}
/*输出:
输出结果:
1,2,3,4,
4,3,2,1,
100,100,100,10
0,
*/
5、双向迭代器支持的操作
不同种类的迭代器能够执行的操作是不同的。
若p和p1都是双向迭代器,则可对p、 p1可进行以下操作:
- ++p, p++ 使p指向容器中下一个元素
- –p, p-- 使p指向容器中上一个元素
- *p 取p指向的元素
- p = p1 赋值
- p == p1 , p!= p1 判断两个迭代器是否相等(即:是否指向同一个元素)、不等
6、随机访问迭代器支持的操作(功能更强)
若p和p1都是随机访问迭代器,则可对p、 p1可进行以下操作:
1)双向迭代器的所有操作
2)以及下列操作
- p += i 将p向后移动i个元素
- p -= i 将p向向前移动i个元素
- p + i 值为: 指向 p 后面的第i个元素的迭代器
- p - i 值为: 指向 p 前面的第i个元素的迭代器
- p[i] 值为: p后面的第i个元素的引用
- p < p1, p <= p1, p > p1, p>= p1 (大小反应的是前后关系。)
- p – p1 : p1和p之间的元素个数
7、各个容器上的迭代器
容器 | 容器上的迭代器别 |
---|---|
vector | 随机访问迭代器 |
deque | 随机访问迭代器 |
list | 双向迭代器(不支持随机访问) |
set/multiset | 双向迭代器(不支持随机访问) |
map/multimap | 双向迭代器(不支持随机访问) |
stack | 不支持迭代器(只能访问栈顶、对头啊等,所以不支持) |
queue | 不支持迭代器(只能访问栈顶、对头啊等,所以不支持) |
priority_queue | 不支持迭代器(只能访问栈顶、对头啊等,所以不支持) |
注意:有的算法,例如sort,binary_search需要通过随机访问迭代器来访问容器中的元素,那么list以及关联容器就不支持该算法!
8、各个容器上的迭代器举例子
(1)vector的迭代器是随机迭代器,遍历 vector 可以有以下几种做法(deque亦然):
vector<int> v(100);
int i;
for(i = 0;i < v.size() ; i ++)
cout << v[i]; //根据下标随机访问
vector<int>::const_iterator ii;
for( ii = v.begin(); ii != v.end ();++ii)//(随机访问迭代器可以比较相等)
cout << * ii;
for( ii = v.begin(); ii < v.end ();++ii )//(随机访问迭代器可以比较大小)
cout << * ii;
//间隔一个输出:(随机访问迭代器可以加一个整数)
ii = v.begin();
while( ii < v.end()) {
cout << * ii;
ii = ii + 2;
}
(2)list 的迭代器是双向迭代器,
//正确的遍历list的方法:
list<int> v;
list<int>::const_iterator ii;
for( ii = v.begin(); ii != v.end ();++ii )()
cout << * ii;
//错误的做法:
for( ii = v.begin(); ii < v.end ();++ii )//双向迭代器不支持 <,list没有 [] 成员函数
cout << * ii;
for(int i = 0;i < v.size() ; i ++)
cout << v[i]; //迭代器没有实现[],因此不能这么写