C++ 之 迭代器

迭代器是一种检查容器内元素并遍历元素的数据类型。C++一般趋向于使用迭代器而不是下标操作。

1.定义和初始化

每种容器都定义了自己的迭代器类型,例如vector:

vector<int>::iterator    iter;    //定义一个名为iter的迭代器

迭代器的初始化

vector<int>    ivec;
vector<int>::iterator    iter1=ivec.bengin();    //将迭代器iter1初始化为指向ivec容器的第一个元素

vector<int>::iterator   iter2=ivec.end();    //将迭代器iter2初始化为指向ivec容器的最后一个元素的下一个位置
  • 如上的定义和初始化把迭代器和容器进行了某种关联,就像把一个指针初始化为指向某一空间地址一样。
  • 如果vector为空,则begin返回的迭代器和end返回的迭代器相同。

2.常用的操作

*iter                //对iter进行解引用,返回迭代器iter指向的元素的引用
iter->men            //对iter进行解引用,获取指定元素中名为men的成员。等效于(*iter).men
++iter                //给iter加1,使其指向容器的下一个元素
iter++
--iter                //给iter减1,使其指向容器的前一个元素
iter--
iter1==iter2        //比较两个迭代器是否相等,当它们指向同一个容器的同一个元素或者都指向同一个容器的超出末端的下一个位置时,它们相等 
iter1!=iter2 

用迭代器遍历容器ivec,并把其每个元素重置为0

vector<int>::iterator iter=ivec.begin()
for(;iter!=ivec.end();++iter)
        *iter=0;

在C++定义的容器类型中,只有vector和queue容器提供迭代器算数运算和除!=和==之外的关系运算:

iter+n     //在迭代器上加(减)整数n,将产生指向容器中钱前面(后面)第n个元素的迭代器。新计算出来的迭代器必须指向容器中的元素或超出容器末端的下一个元素
iter-n

iter1+=iter2        //将iter1加上或减去iter2的运算结果赋给iter1。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素
iter1-=iter2

iter1-iter2            //两个迭代器的减法,得出两个迭代器的距离。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素

>,>=,<,<=        //元素靠后的迭代器大于靠前的迭代器。两个迭代器必须指向容器中的元素或超出容器末端的下一个元素

3.const_iterator

const_iterator类型的迭代器只能读取容器中的元素,不能用于改变其值。之前的例子中,普通的迭代器可以对容器中的元素进行解引用并修改。

for(vector<int>::const_iterator iter=ivec.begin();iter!=ivec.end();++iter)
     cout<<*iter<<endl;       //合法,读取容器中元素值

for(vector<int>::const_iterator iter=ivec.begin();iter!=ivec.end();++iter)
    *iter=0;        //不合法,不能进行写操作

const iterator:对const iterator迭代器进行声明时,必须对迭代器进行初始化,并且一旦初始化后就不能修改其值。

vector<int>    ivec(10);
const    vector<int>::iterator    iter=ivec.begin();
*iter=0;    //合法,可以改变其指向的元素的值
++iter;    //不合法,无法改变其指向的位置

4.迭代器失效

分三种情况考虑:
1).数组型数据结构:该数据结构的元素是分配在连续的内存中,insert和erase操作,都会使得删除点和插入点之后的元素挪位置,所以,插入点和删除点之后的迭代器全部失效,也就是说insert(*iter)(或erase(*iter)),然后再iter++,是没有意义的
解决方法:erase(*iter)的返回值是下一个有效迭代器的值。 iter =cont.erase(iter)

2).链表型数据结构:对于list型的数据结构,使用了不连续分配的内存,删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器。
解决办法有两种,erase(*iter)会返回下一个有效迭代器的值,或者erase(iter++).

3).树形数据结构: 使用红黑树来存储数据,插入不会使得任何迭代器失效
删除运算使指向删除位置的迭代器失效,但是不会失效其他迭代器。erase迭代器只是被删元素的迭代器失效,但是返回值为void,所以要采用erase(iter++)的方式删除迭代器。
注意:经过erase(iter)之后的迭代器完全失效,该迭代器iter不能参与任何运算,包括iter++,*ite

猜你喜欢

转载自blog.csdn.net/u013402321/article/details/79884064