C++中的顺序容器

来源:互联网 发布:程序员如何年薪百万 编辑:程序博客网 时间:2024/04/30 17:09

容器分为两种类型:顺序容器、关联容器

这里介绍顺序容器

顺序容器分为三种类型:vector、list、deque

三种顺序容器的适配器:stack、queue、priority_queue

容器只定义了少量操作,大多数的额外操作则由算法库提供。

1.要定义一个容器类型的对象,必须包含相关的头文件:

#include<vector>

#include<list>

#include<deque>

2.初始化

C为容器类型名,T为元素类型。

C<T> c;   创建一个元素类型为T的C类型容器c(适用于所有容器)。

C c(c2);   创建c2的副本,c与c2必须具有相同的容器类型,并存放相同类型的元素(适用于所有容器)。

C c(b,e);  创建c,其元素是迭代器b和e标示的范围内的元素的副本(适用于所有容器)。

C c(n,t);    用n个值为t的元素创建容器c,t必须是C的元素类型的值,或者是可转化为该类型的值(只适用于顺序容器)。

C c(n);      创建c,有n个初始化值元素(只适用于顺序容器)。

接受容器大小做形参的构造函数只适用于顺序容器,而关联容器不支持这种初始化。

3.容器内元素的类型约束

必须满足两个约束:元素类型必须支持赋值运算、元素类型的对象必须可以复制

除了引用外,所有内置或复合类型都可以做元素类型;除了输入输出(IO)标准库(不支持复制或赋值)类型外,所有其他标准库类型都是有效的容器元素类型。特别地,容器本身也满足要求,所以,可以定义元素本身就是容器类型的容器。

4.迭代器和迭代器范围

常用的迭代器运算:

*iter                返回迭代器iter所指向的元素的引用

iter->mem    对iter进行解引用,获取指定元素中名为mem的成员。等效于(*iter).mem

++iter            指向容器中的下一个元素

iter++            同上

--iter               指向容器中的下一个元素

iter--             同上

iter1==iter2   

iter1!=iter2    比较两个迭代器是否相等(或不等)。当指向同一个容器中的同一个元素,或者都指向同一个容器的超出末端的下一个位置时,两个迭代器相等。

C++中,vector和deque提供两种重要的运算集合:迭代器算术运算、使用除了==和!=之外的(这两个也可用)关系操作符来比较两个迭代器。

为什么只适用于这两个容器?因为只有这两个容器为其元素提供快速、随机的访问。它们确保可根据元素位置直接有效地访问指定的容器元素。

迭代器范围:

first和last:包括迭代器first指向的元素,以及从first开始一直到迭代器last指向的位置之前的所有元素,但不包括last。此类元素范围称为左闭合区间,[first,last)。last决不能在first之前。

begin和end:指向容器内第一个元素和最后一个元素的下一位置的迭代器,这两个迭代器通常用于标记包含容器内所有元素的迭代器范围。

last和end都不是指向元素范围的最后一个元素,而是指向最后一个元素的下一位置。

5.在顺序容器中添加元素

c.push_back(t)  在容器c的尾部添加值为t的元素。返回void类型。

c.push_front(t)  在容器c的前段添加值为t的元素。返回void类型(只适用于list和deque容器类型)。

c.insert(p,t)        在迭代器p所指向的元素前面插入值为t的新元素。返回指向新添加元素的迭代器。

c.insert(p,n,t)     在迭代器p所指向的元素前面插入n个值为t的新元素。返回void类型。

c.insert(p,b,e)    在迭代器p所指向的元素前面插入由迭代器b和e标记的范围内的元素。返回void类型。

注意:1.任何insert或push操作都可能导致迭代器失效。当编写循环将新元素插入到vector或deque容器中时,程序必须确保迭代器在每次循环后都得到更新。

             2.不要存储end操作返回的迭代器。添加或删除vector或deque容器内的元素都会导致存储的迭代器失效。

6.顺序容器大小的操作

c.size()             返回容器c中的元素个数。返回类型:c::size_type

c.max_size()   返回容器c可容纳的最多元素个数。返回类型:c::size_type

c.empty()          返回标记容器大小是否为0的布尔值。

c.resize(n)        调整容器c的长度大小,使其能容纳n个元素,如果n<c.size(),则删除多出来的元素;否则,添加采用值初始化的新元素。

c.resize(n,t)      调整容器c的大小,使其能容纳n个元素,所有新添加的元素值都为t。

7.访问元素

如果容器非空,那么容器类型的front和back成员将返回容器内第一个或最后一个元素的引用。

访问顺序容器内元素的操作:

c.back()    返回c的最后一个元素的引用。如果c为空,则该操作未定义。

c.front()    返回c的第一个元素的引用。如果c为空,则该操作未定义。

c[n]           返回下标为n的元素的引用。如果n<0或n>c.size(),则该操作未定义。(只适用于vector和deque容器)

c.at(n)      返回下标为n的元素的引用。如果下标越界,则该操作未定义。(只适用于vector和deque容器)

at函数的行为和下标运算相似,但是如果给出的下标无效,at函数将会抛出out_of_range异常。

8.删除元素

c.pop_back()   删除c的最后一个元素。返回void。如果c为空,则该函数未定义。

c.pop_front()   删除c的第一个元素。返回void。如果c为空,则该函数未定义。(只适用于list或deque容器)

c.erase(p)       删除p所指向的元素,返回一个迭代器,指向被删除元素后面的元素。如果p指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端                             的下一位置。如果p本身就是指向超出末端的下一位置的迭代器,则该函数未定义。

c.erase(b,e)   删除迭代器b和e所标记的范围内的所有元素。返回一个迭代器,指向被删除元素段后面的元素。如果e本身就是指向超出末端的下一个位置的迭                         代器,则返回的迭代器也指向容器的超出末端的下一位置。

c.clear()          删除c内的所有元素。返回void。

注意:在删除元素前,必须确保迭代器不是end迭代器。使用erase操作删除单个元素必须确保该元素确实存在,否则erase操作的行为未定义。

通常,程序员必须在容器中找到要删除的元素后,才使用erase操作。寻找一个指定元素的最简单的方法是使用标准库的find算法。为了使用find函数或其他泛型算法,在编程时,必须将algorithm头文件包含进来。find函数需要一对标记查找范围的迭代器以及一个在该范围内查找的值作参数。查找完成后,该函数返回一个迭代器,它指向具有指定值的第一个元素,或超出末端的下一位置。

erase、pop_front、pop_back函数使指向被删除元素的所有迭代器失效。对于vector容器,指向删除点后面的元素的迭代器通常也会失效。而对于deque容器,如果删除时不包含第一个元素或最后一个元素,那么该deque容器相关的所有迭代器都会失效。

0 0
原创粉丝点击