C++Primer 顺序容器

来源:互联网 发布:人之无情乃可至于是乎 编辑:程序博客网 时间:2024/05/01 21:39

1.顺序容器的概念sequential container:将单一类型元素聚集起来,并根据位置来存储和访问元素的容器 称为顺序容器。

2.标准库定义的三种顺序容器类型:vector,list,deque。

  标准库定义的三种容器适配器:stack,queue,priority_queue。

3.顺序容器的定义和初始化

(1)默认构造函数:C<T> c,创建一个名为c的空容器变量,存放的元素类型是T。

  vector<string> svec;  list<int> ilist;


(2)将一个容器初始化为另一个容器的副本时,容器类型和元素类型都要匹配。

  vector<int> ivec;  vector<int> ivec2(ivec);

(3)初始化为一段元素副本时,容器类型不需要一致。只需要两个迭代器,一个指向元素的开始地址,一个指向元素末端的下一个位置。

  vector<string>::iterator mid = svec.begin()+svec.size()/2;  deque<string> front(svec.begin(),mid);  deque<string> back(mid,svec.end());

(4)接受容器大小做形参的构造函数只适用于顺序容器。

  const list<int>::size_type list_type = 64;  list<string> slist(list_size,"hello");  list<string> llist(list_size);

4.容器内元素类型:必须支持赋值和复制,标准库类型中除了IO库类型,其他都是有效的容器元素类型,包括容器元素自己。

  vector< list<int> >

5.迭代器first和last如果满足以下条件,则可形成一个迭代器范围:它们指向同一个容器中的元素或超出末端的下一个位置。如果两个迭代器不同,则last决不能位于first之前。使用左闭合区间的意义在于可以用一个循环判断还有元素,并且在循环内确保*first是安全的。

(1)查找vector中元素的值:

#include <iostream>#include <vector>#include <string>using namespace std;vector<int>::iterator Find(vector<int>::iterator beg,vector<int>::iterator end,int val){while(beg!=end)  if(*beg == val) break; else ++beg;return beg;}int main(){ int ia[] = {0,1,2,3,4,5,6};    vector<int> ivec(ia,ia+7);cout<<"Enter an integer: "<<endl;int val;cin>>val;vector<int>::iterator it;it = FindInt(ivec.begin(),ivec.end(),val);if(it!=ivec.end())cout<<val<<" is an element of vector!"<<endl;elsecout<<val<<" is not an element of vector!"<<endl;system("pause");return 0;}

(2)向vector中写入多个string:

string str;vector<string> svec;cout<<"Enter some strings: "<<endl;while(cin>>str)   svec.push_back(str);for(vector<string>::iterator iter=svec.begin();iter!=svec.end();++iter)   cout<<*iter<<endl;


7.顺序容器的操作

(1)添加元素container.push_back(t),c.push_front(t),后者只适用于list和deque容器类型

(2)插入c.insert(p,t),c.insert(p,n,t),c.insert(p,b,e),即便vector不支持push_front也可以用insert做等效操作:insert(v.begin(),t)

(3)添加和删除操作都会使迭代器失效,要避免存储迭代器返回结果。

(4)容器的关系操作符:前提是容器内的元素类型支持关系操作符。

(5)容器大小:c.resize(n),不足补零,多余去掉。

(6)访问元素:c.back(),c.front()返回元素而不是指针。c[n]和c.at(n)等价,只适用于vector和deque。

(7)删除:c.erase(p)返回的是指向下一个元素的迭代器。c.pop_back(),c.pop_front(),后者只用于list和deque。

(8)赋值:流程是先删除后插入,必须在容器类型和元素类型均相同是使用。

     assign:可以是不同容器类型之间的。

     swap:不会删除或插入元素,迭代器不会失效,只不过迭代器指向了不同的容器,但还是指向同一个字符串。


8.vector的内存管理

vector中的元素以连续的方式存放,若添加一个元素时已经没了空间就必须重新分配内存。vector采用的策略是预留了额外的存储区,用于存放新添加的元素。c.size()表示的是当前容器的长度,c.capacity()表示的是容器在必须分配新存储空间之前可以存储的元素综述。初始时,size和capacity均为0.之后capacity>size,当size逐渐逼近到等于capacity时,capacity会重新分配另一组内存。


9.deque,list,vector的区别:

(1)存储分配:

deque是双向开口的连续性存储空间。虽说是连续性存储空间,但这种连续性只是表面上的,实际上它的内存是动态分配的,它在堆上分配了一块一块的动态储存区,每一块动态存储去本身是连续的,deque自身的机制把这一块一块的存储区虚拟地连在一起。

list是链式存储。vector是顺序存储。

(2)存取和删除插入的效率:

deque在开始和最后添加元素都一样快,并提供了随机访问方法,vector一样使用[]访问任意元素,但是随机访问速度比不上vector,因为它要内部处理堆跳转。

vector是可以快速地在最后添加删除元素,并可以快速地访问任意元素。但是在中间插入删除需要移动元素位置。
list是可以快速地在所有地方添加删除元素,但是访问元素需要遍历链表。
(3)内存分配:

vector需要事先分配capacity大于size,再size超过capacity时需要重新分配和复制所有元素。
deque有保留空间.另外,由于deque不要求连续空间,所以可以保存的元素比vector更大,这点也要注意一下.还有就是在前面和后面添加元素时都不需要移动其它块的元素,所以性能也很高。

list不需要事先分配内存。


10.再谈string类型:

(1)在某些方面可将string类型视为字符容器。string提供和vector相同的操作,除了栈方式front,back,pop_back操作。

(2)特有操作:

s.substr:返回string对象子串。

s.append(a):字符添加到末尾。s.replace()字符插入到某些位置。

s.find:返回的是元素出现的下标,类型是string::size_type。

s.compare()比较类似于strcmp。


11.容器适配器:stack,queue,priority_queue,让一种已存在的容器类型采用另一种不同的抽象类型的工作方式实现。adaptor本身定义了操作,这些操作是通过某种基本的容器操作实现的。比如,默认的stack和queue是基于deque容器实现的,而priority_queue则是在vector容器上实现的。也就是说stack中的操作s.pop(),s.top(),s.push(item)都是通过deque容器的基本操作实现的,只是在定义stack<T> 变量之后不会去关系如何使用deque容器的操作,而是直接使用定义在stack上的操作。

(1)初始化:可以用deque<int>类型的容器初始化一个栈。

stack<int> stk(deq);

(2)覆盖基础容器类型:虽然适配器有默认关联的基础容器类型。但也可以改变。

stack可以建立在vector,list,deque之上。queue可以建立在list和deque之上(需要push_front操作)。priority_queue可以建立在vector和deque之上(需要随机存取操作)。

stack<string, vector<string> >str_stk;

(3)栈适配器:stack<int> intStack;

 s.empty(),s.size(),s.pop()出栈删除栈顶元素,s.top()返回栈顶元素,s.push(item)入栈。

(4)队列和优先级队列:公用操作q.empty(),q.size(),q.pop()删除队首元素

FIFO队列:q.front()返回队首元素,q.back()返回队尾元素,q.push(item)在队尾压入一个元素。

优先级队列:q.top()返回具有最高优先级的元素值。q.push(item)在基于优先级的适当位置插入新元素。


0 0
原创粉丝点击