您的位置:首页 > 编程语言 > C语言/C++

C++ primer 读书笔记系列——(6)顺序容器

2010-09-03 22:27 295 查看
顺序容器类型:

顺序容器:

vector 支持快速随即访问

list 支持快速插入/删除

deque 双端队列

顺序容器适配器:

stack 后进先出栈(LIFO)

queue 先进先出队列(FIFO)

priority_queue 有优先级管理的队列

(一)顺序容器的定义

1.容器的定义和初始化

#include<iostream>
#include<vector>

using namespace std;

int main()
{
vector<int> ivec;

for(vector<int>::size_type ix=0;ix!=10;ix++) //初始化ivec;
{
ivec.push_back(100+ix);
}

for(vector<int>::const_iterator iter1=ivec.begin()+ivec.size()/2;iter1!=ivec.end();iter1++)
//打印ivec
{
cout<<*iter1<<" ";
}
cout<<endl;

vector<int> ivec1(ivec.begin(),ivec.end());
//将ivec1初始化为ivec的一个副本,此句可置换为ivec1(ivec);

for(vector<int>::const_iterator iter=ivec1.begin();iter!=ivec1.end();iter++) //打印ivec1
{
cout<<*iter<<" ";
}
cout<<endl;

return 0;
}


代码运行结果:

105 106 107 108 109
100 101 102 103 104 105 106 107 108 109

2.容器内元素的类型约束条件

a.元素类型必须支持赋值运算

b.元素类型的对象必须可以复制

例如:我们定义了一个类foo,但该类没有定义默认的构造函数,但提供了一个需要int型形参的构造函数;

现在,考虑下面的声明:

vector<foo> empty; //ok;no need for element default constructor

vector<foo> bad(10) //error;no default constructor for foo

vector<foo> ok(10,1) //ok:each element initialized to1

(二)迭代器和迭代器范围

迭代器的解引用操作:(*iter).mem与iter->mem等效。

使迭代器失效的容器操作:一些容器操作会修改容器内在状态或移动容器内元素,这样的操作会使所有被移动的元素的迭代器失效,也可能同时使其他迭代器失效,使用无效迭代器是没有意义的,可能会导致与悬垂指针相同的问题。 例如:每种容器都定义了一种或多种erase函数,这些函数提供了删除元素的功能,当执行此函数后,指向已删除元素的跌倒器是没有任何意义的,毕竟,该迭代器指向了容器中不再存在的元素。

无法检查迭代器是否有效,也无法通过测试来发现迭代器是否已经失效。任何无效迭代器的使用都可能导致运行时出错。但程序不一定崩溃,否则,检查这种错误会容易些。

(三)顺序容器的操作

1.reverse_iterator 和 rbegin,rend的结合用法:

#include<iostream>
#include<vector>

using namespace std;

int main()
{
vector<int> ivec;

for(vector<int>::size_type ix=0;ix!=10;ix++)
//初始化ivec;
{
ivec.push_back(100+ix);
}

vector<int>::reverse_iterator iter=ivec.rbegin();
// rbegin()返回的为逆序迭代器,该迭代器指向容器最后一个元素
vector<int>::reverse_iterator iter1=ivec.rend();
//rend()返回的为逆序迭代器,该迭代器指向容器第一个元素的前一个位置

for(; iter!=iter1;iter++) //打印ivec;
{
cout<<*iter<<" ";
}
cout<<endl;

return 0;
}


程序执行结果为:

109 108 107 106 105 104 103 102 101 100

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

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所指向的元素前面插入由迭代器p和e标记的范围内的元素,返回void类型

#include<iostream>
#include<vector>
#include<list>

using namespace std;

int main()
{
list<int> ivec;

for(list<int>::size_type ix=0;ix!=10;ix++) //在ivec尾部压入10个元素
{
ivec.push_back(ix);
}

for(list<int>::size_type iy=0;iy!=10;iy++) //在ivec头部压入10个元素
{
ivec.push_front(iy);
}

for(list<int>::const_iterator iter=ivec.begin();iter!=ivec.end();iter++)
//输出ivec
{
cout<<*iter<<" ";
}
cout<<endl;

ivec.insert(ivec.begin(),10,11);//在ivec的头部添加10个元素值11

for(list<int>::iterator iter3=ivec.begin();iter3!=ivec.end();iter3++)
//输出ivec
{
cout<<*iter3<<" ";
}
cout<<endl;

vector<int> ivec1;
ivec1.insert(ivec1.begin(),10,11); //在容器ivec1第一个元素前面插入10个11

for(vector<int>::const_iterator iter1=ivec1.begin();iter1!=ivec1.end();iter1++)
//打印ivec1
{
cout<<*iter1<<" ";
}
cout<<endl;

return 0;
}


程序运行结果:

9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
11 11 11 11 11 11 11 11 11 11 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
11 11 11 11 11 11 11 11 11 11

可以看到,vector虽然不支持push_front()操作,但可以用insert(s.front(),t)来替代此操作;

3.容器大小的操作

c.size() 返回容器中元素的个数

c.max_size() 返回容器中可容纳的最多的元素的个数

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

c.resize(n) 调整容器元素的大小,使其可容纳n个元素

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

#include<iostream>
#include<vector>
#include<list>

using namespace std;

int main()

{
vector<int> ivec;

for(vector<int>::size_type ix=0;ix!=10;ix++) //初始化ivec
{
ivec.push_back(ix);
}

//输出Ivec信息
cout<<"the elements of ivec is:"<<endl;
for(vector<int>::iterator iter1=ivec.begin();iter1!=ivec.end();iter1++)
{
cout<<*iter1<<" ";
}
cout<<endl;
cout<<"ivec's size is: "<<ivec.size()<<endl;
cout<<"ivec's max_size is: "<<ivec.max_size()<<endl<<endl;

//使用resize(t)函数重新调整ivec大小,并显示ivec信息
ivec.resize(25);
cout<<"after resize to 25,now the elements of ivec is"<<endl;
for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();iter++)
{
cout<<*iter<<" ";
}
cout<<endl;
cout<<"now the size of ivec is:"<<ivec.size()<<endl;
cout<<"now the max_size of ivec is:"<<ivec.max_size()<<endl<<endl;

//使用resize(n,t)函数重新调整ivec大小,并显示ivec信息
ivec.resize(50,121);
cout<<"after resize to 50,now the elements of ivec is"<<endl;
for(vector<int>::iterator iter2=ivec.begin();iter2!=ivec.end();iter2++)
{
cout<<*iter2<<" ";
}
cout<<endl;
cout<<"now the size of ivec is:"<<ivec.size()<<endl;
cout<<"now the max_size of ivec is:"<<ivec.max_size()<<endl<<endl;

return 0;
}


程序运行结果:

the elements of ivec is:
0 1 2 3 4 5 6 7 8 9
ivec's size is: 10
ivec's max_size is: 1073741823

after resize to 25,now the elements of ivec is
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
now the size of ivec is:25
now the max_size of ivec is:1073741823

after resize to 50,now the elements of ivec is
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 121 121 121 121 121 121 121 12
1 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121
now the size of ivec is:50
now the max_size of ivec is:1073741823

事实上,resize操作可能会使迭代器失效,在vector或deque上做resize操作可能会使其所有的迭代器都失效。

对于所有的容器类型,如果resize压缩了容器大小,则指向已删除的元素的迭代器失效。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: