c++primer第九章顺序容器 小结--9

100 篇文章 8 订阅

第九章---顺序容器 

这一章节实际上是讲了c++非常重要的一部分-----STL,现在只是学习最基本的容器的操作,今后还想学习源码剖析这本书。


 1、顺序容器内的元素按位置进行存储和访问。元素的排列次序与元素值无关,而是由元素添加到容器的次序决定的,新的c++11标准库定义了六种顺序容器类型:vector,list,deque,forward_list,array(比内置数组更加的安全,快速),string(实际上它并不是顺序容器,只是它可以提供和顺序容器许多相关的操作,所以可以类似的理解成顺序),它们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价。容器仅定义少量操作,大多数额外操作由算法库提供。在后面的泛型算法章节有更加详细的描述。


 2、为了定义容器对象首先要包含相关头文件,如#include<vector>,#include<list>,#include<deque>,所有的容器都是类模板,必须为容器指定容器存放的元素类型进行实例化。所有的容器都提供了默认构造函数,除此之外还提供其他构造函数。如下:

1:C<T> c;默认构造函数。

2:C c(c2);复制构造。

3:C c(b,e);用b,e标示的范围创建c,b、e为迭代器。

4:C c(n,t)用n个t的元素创建c。5:C c(n)。创建有n个元素的c。调用默认构造函数。
将一个容器复制给另一个容器时,容器类型和元素类型都必须匹配。vector<int> ivec;vector<int>ivec2(ivec);系统允许通过传递一对迭代器,将一个容器的一部分元素赋值给另一个容器。迭代器指向要复制的第一个元素和最后一个元素的下一位置。

容器元素必须满足一下两个条件:
1:元素类型必须支持赋值运算。
2:元素类型对象必须可以复制。
引用类型因为它不支持一般意义上的赋值运算(从一而终,)IO库类型和auto_ptr类型均不能作为容器元素类型,原因与引用类似。


3、详细介绍各容器

vector :

vector和built-in数组类似,是一个在堆上建立的一维数组,它拥有一段连续的内存空间,并且起始地址不变,因此它能非常好的支持随即存取,即[]操作符。vector因为存储在上,所以支持erase(), resieze()(重新划分容器容量)等操作; vector不用担心越界当空间不够用的时候,系统会自动按照一定的比例(对capacity( )大小)进行扩充。在vector序列末尾添加(push_back( ))或者删除(pop_back( ))对象效率高,在中间进行插入或删除效率很低,主要是要进行元素的移动和内存的拷贝,原因就在于当内存不够用的时候要执行重新分配内存,拷贝对象到新存储区,销毁old对象,释放内存等操作,如果对象很多的话,这种操作代价是相当高的。为了减少这种代价,使用vector最理想的情况就是事先知道所要装入的对象数目,用成员函式 reserve( ) 预定下来;vector最大的优点莫过于是检索(用operator[ ])速度在容器中是最快的。

 list :

 list的本质是一个双向链表(根据sgistl源代码),内存空间不连续,通过指针进行操作。说道链表,它的高效率首先表现是插入,删除元素,进行排序等等需要移动大量元素的操作。显然链表没有检索操作operator[ ], 也就是说不能对链表进行随机访问,而只能从头至尾地遍历,这是它的一个缺陷。list有不同于前两者的某些成员方法,如合并list的方法splice( ), 排序sort( ),交换list 的方法swap( )等等。

deque :

 deque是一个double-ended。queue是由多个连续内存块构成,deque是list和vector的兼容,分为多个块,每一个块大小是512字节,块通过map块管理,map块里保存每个块得首地址。因此该容器也有索引操作operator[ ],效率没vector高。另外,deque比vector多了push_front( ) & pop_front( )操作。在两端进行此操作时与list的效率 差不多。

Forward list:
前向链表是序列容器,插入和擦除操作序列内的任何地方。前向链表的实现方式和单链表相同,在序列中顺序保存每个元素指向下一个元素的关联。forward_list容器与list容器的主要设计区别是list保持内部唯一的一个链接到下一个元素,而后者则保持每个元素的两个链接:一个指向下一个元素和一个前一个。list允许高效在两个方向迭代,但每个元素的消耗额外的存储空间,并轻微较高的时间开销插入和删除元素的迭代。forward_list对象只能向前遍历。与其他的基本标准序列容器(array,vector和deque)相比,forward_list一般在容器内的任何位置中的元素的插入、提取和移动操作效率更高,因此在算法中较密集的使用这些操作,例如排序算法。相比其他序列容器,forward_lists的主要缺点是缺乏直接访问他们的位置的元素,例如,要进入第六个元素在forward_list的一个遍历从一开始就到那个位置,这需要线性时间之间的距离。

std::array

array是一个支持随机访问且大小(size)固定的容器(译注:可以认为是一个紧缩版的vector吧)。它有如下特点:
1.不预留多余空间,只分配必须空间(译注:size() == capacity())。2.可以使用初始化表(initializer list)的方式进行初始化。
3.保存了自己的size信息。4.不支持隐式指针类型转换。换句话说,可以认为它是一个很不错的内建数组类型,但是和内置数组不是一同一个东西。


4、各容器常见操作

4.1添加元素
有三类函数push_back()、push_front()、insert(),用insert()在指定位置插入单个元素时,返回指向新元素的迭代器,其他的都返回void
4.2容器大小操作
size(), max_size(), empty() resize()。resize()能删除多出来的元素。
4.3访问元素
用迭代器迭代容器或者使用下标操作(list不支持下标操作)
4.4删除元素
erase()(返回指向删除元素后的迭代器), clear(), pop_back(), pop_front() (pop_操作只删除元素,不返回删除的元素值,返回void)
assign赋值操作 , swap 交换容器操作(不会破坏迭代器)


5、容器适配器

顺序容器还有三种适配器,主要作用是包装其它容器使之具有某种操作特征

stack 堆栈适配器             ( 可用的容器类型 vector deque list)

queue 队列适配器             ( 可用的容器类型 deque list) 

priority_queue 优先级队列   (可用的容器类型 deque vector)

6、选择准则 

    1. 如果我们需要随机访问一个容器则vector要比list好得多
    2. 如果我们已知要存储元素的个数则vector 又是一个比list好的选择。
    3. 如果我们需要的不只是在容器两端插入和删除元素则list显然要比vector好 
    4. 除非我们需要在容器首部插入和删除元素否则vector要比deque好
    5. 如果只在容易的首部和尾部插入数据元素,则选择deque
    6. 如果只需要在读取输入时在容器的中间位置插入元素,然后需要随机访问元素,则可考虑输入时将元素读入到一个List容器,接着对此容器重新拍学,使其适合顺序访问,然后将排序后的list容器复制到一个vector容器中。
一般来说vector是很好的选择。







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值