标签:style color strong 使用 数据 set
首先对于vector而言,添加和删除操作可能使容器的部分或者全部迭代器失效。那为什么迭代器会失效呢?vector元素在内存中是顺序存储,试想:如果当前容器中已经存在了10个元素,现在又要添加一个元素到容器中,但是内存中紧跟在这10个元素后面没有一个空闲空间,而vector的元素必须顺序存储一边索引访问,所以我们不能在内存中随便找个地方存储这个元素。于是vector必须重新分配存储空间,用来存放原来的元素以及新添加的元素:存放在旧存储空间的元素被复制到新的存储空间里,接着插入新的元素,最后撤销旧的存储空间。这种情况发生,一定会导致vector容器的所有迭代器都失效。我们看到实现上述所说的分配和撤销内存空间的方式以实现vector的自增长性,效率是极其低下的。为了使vector容器实现快速的内存分配,实际分配的容器会比当前所需的空间多一些,vector容器预留了这些额外的存储区,用来存放新添加的元素,而不需要每次都重新分配新的存储空间。你可以从vector里实现capacity和reserve成员可以看出这种机制。capacity和size的区别:size是容器当前拥有的元素个数,而capacity则指容器在必须分配新存储空间之前可以存储的元素总数。
vector迭代器的失效情况:
1.当插入(push_back)一个元素后,end操作返回的迭代器肯定失效。
2.当插入(push_back)一个元素后,capacity返回值与没有插入元素之前相比有改变,则需要重新加载整个容器,此时begin和end操作返回的迭代器都会失效。
删除时,指向该删除节点的迭代器失效
list<int> intList;
(1) vector
内部数据结构:数组。
随机访问每个元素,所需要的时间为常量。
(2)deque
内部数据结构:数组。
键可以不唯一。
其它特点与set相同。
1. 容器的iterator类型
每种容器类型都定义了自己的迭代器类型,如vector:
vector::iterator iter;
这条语句定义了一个名为iter的变量,它的数据类型是由vector定义的iterator类型。每个标准库容器类型都定义了一个名为iterator的成员,这里的iterator与迭代器实际类型的含义相同。
2. begin和end操作
每种容器都定义了一对命名为begin和end的函数,用于返回迭代器。如果容器中有元素的话,由begin返回的迭代器指向第一个元素:
vector::iterator iter = ivec.begin();
上述语句把iter初始化为由名为begin的vector操作返回的值。假设vector不空,初始化后,iter即指该元素为ivec[0]。
由end操作返回的迭代器指向vector的"末端元素的下一个"。通常称为超出末端迭代器(off-the-end iterator),表明它指向了一个不存在的元素。如果vector为空,begin返回的迭代器与end返回的迭代器相同。
由end操作返回的迭代器并不指向vector中任何实际的元素,相反,它只是起一个哨兵(sentinel)的作用,表示我们已处理完vector中所有元素。
3. vector迭代器的自增和解引用运算
迭代器类型定义了一些操作来获取迭代器所指向的元素,并允许程序员将迭代器从一个元素移动到另一个元素。
迭代器类型可使用解引用操作符(*操作符)来访问迭代器所指向r 元素:
*iter = 0;
解引用操作符返回迭代器当前所指向的元素。假设iter指向vector对象ivec的第一个元素,那么*iter和ivec[0]就是指向同一个元素。上面这个语句的效果就是把这个元素的值赋为0。
迭代器使用自增操作符向前移动迭代器指向容器中下一个元素。从逻辑上说,迭代器的自增操作和int型对象的自增操作类似。对 int对象来说,操作结果就是把int型值"加1",而对迭代器对象则是把容器中的迭代器"向前移动一个位置"。因此,如果iter指向第一个元素,则++iter指向第二个元素。
由于end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
4. 迭代器的其他运算
另一对可执行于迭代器的操作就是比较:用==或!=操作符来比较两个迭代器,如果两个迭代器对象指向同一个元素,则它们相等,否则就不相等。
5. 迭代器应用的程序示例
假设已声明了一个vector型的ivec变量,要把它所有元素值重置为0,可以用下标操作来完成:
// reset all the elements in ivec to 0
for (vector::size_type ix = 0; ix != ivec.size(); ++ix)
ivec[ix] = 0;
上述程序用for循环遍历ivec的元素,for循环定义了一个索引ix,每循环迭代一次ix就自增1。for循环体将ivec的每个元素赋值为0
关于迭代器
(1)特征与操作
l 迭代器的基本特征有:
解除——支持解除引用(dereference)操作,以便可以访问它引用的值。即,如果p是一个迭代器,则应该对*p和p->进行定义(似指针);
赋值——可将一个迭代器赋给另一个迭代器。即,如果p和q都是迭代器,则应该对表达式p=q进行定义;
比较——可将一个迭代器与另一个迭代器进行比较。即,如果p和q都是迭代器,则应该对表达式p==q和p!=q进行定义;
遍历——可以使用迭代器来遍历容器中的元素,这可以通过为迭代器p定义++p和p++操作来实现。
迭代器的操作有:
读——通过解除引用*来间接引用容器中的元素值,例如x = *p;
写——通过解除引用*来给容器中的元素赋值,例如*p = x;
访问——通过下标和指向引用容器中的元素及其成员,例如p[2]和p->m
迭代——利用增量和减量运算(++和--、+和-、+=和-=)在容器中遍历、漫游和跳跃,例如p++、--p、p+5、p-=8
比较——利用比较运算符(==、!=、<、>、<=、>=)来比较两个迭代器是否相等或谁大谁小,例如if(p < q)……;、wihle(p != c.end())……;
(2)分类
根据迭代器所支持的操作不同,在STL中定义了如下5种迭代器:
l 输入迭代器(input iterator)——用于读取容器中的信息,但不一定能够修改它。
输入迭代器iter通过解除引用(即*iter),来读取容器中其所指向元素之值;
为了使输入迭代器能够访问容器中的所有元素的值,必须使其支持(前/后缀格式的)++ 操作符;
输入迭代器不能保证第二次遍历容器时,顺序不变;也不能保证其递增后,先前指向的值不变。即,基于输入迭代器的任何算法,都应该是单通(single-pass)的,不依赖于前一次遍历时的值,也不依赖于本次遍历中前面的值。
可见输入迭代器是一种单向的只读迭代器,可以递增但是不能递减,而且只能读不能写。适用于单通只读型算法。
l 输出迭代器(output iterator)——用于将信息传输给容器(修改容器中元素的值),但是不能读取。例如,显示器就是只能写不能读的设备,可用输出容器来表示它。也支持解除引用和++操作,也是单通的。所以,输出迭代器适用于单通只写型算法。
l 前向迭代器(forward iterator正向迭代器)——只能使用++操作符来单向遍历容器(不能用--)。与I/O迭代器一样,前向迭代器也支持解除引用与++操作。与I/O迭代器不同的是,前向迭代器是多通的(multi-pass)。即,它总是以同样的顺序来遍历容器,而且迭代器递增后,仍然可以通过解除保存的迭代器引用,来获得同样的值。另外,前向迭代器既可以是读写型的,也可以是只读的。
l 双向迭代器(bidirectional iterator)——可以用++和--操作符来双向遍历容器。其他与前向迭代器一样,也支持解除引用、也是多通的、也是可读写或只读的。
l 随机访问迭代器(random access iterator)——可直接访问容器中的任意一个元素的双向迭代器。
可见,这5种迭代器形成了一个层次结构:I/O迭代器(都可++遍历,但是前者只读/后者只写)最基本、前向迭代器可读写但只能++遍历、双向迭代器也可读写但能++/--双向遍历、随机迭代器除了能够双向遍历外还能够随机访问。
(3)指针与迭代器
既然迭代器是广义的指针,那么指针本身是不是迭代器呢?其实,指针满足所有迭代器的要求,所以,指针就是一种迭代器。
迭代器是泛型算法的接口,而指针是迭代器。所以,各种STL算法,也可以使用指针,来对非标准容器(如数组)进行操作。即,利用指针做迭代器,可以将STL算法用于常规数组。
例如排序函数sort:
sort(Ran first, Ran last); // Ran表示随机访问迭代器
对容器c为:
sort(c.begin(), c.end());
对数组a可以改为:(const int SIZE = 100; float a[SIZE];)
sort(a, a + SIZE);
又例如复制函数copy:
copy(In first, In last, Out res); // In和Out分别表示输入和输出迭代器
对容器c<int>可为:(ostream_iterator<int> out_iter(cout);)
copy(c.begin(), c.end(), out_iter);
对数组a可以改为:(const int SIZE = 100; float a[SIZE];)
copy(a, a + SIZE, c.begin());
标签:style color strong 使用 数据 set
原文地址:http://blog.csdn.net/mr_chenping/article/details/30548507