STL中vector、list、deque和map的区别
1 vector
向量 相当于一个数组
在内存中分配一块连续的内存空间进行存储。支持不指定vector大小的存储。STL内部实现时,首先分配一个非常大的内存空间预备进行存储,即capacituy()函数返回的大小,当超过此分配的空间时再整体重新放分配一块内存存储,这给人以vector可以不指定vector即一个连续内存的大小的感觉。通常此默认的内存分配能完成大部分情况下的存储。
优点:(1) 不指定一块内存大小的数组的连续存储,即可以像数组一样操作,但可以对此数组
进行动态操作。通常体现在push_back() pop_back()
(2) 随机访问方便,即支持[ ]操作符和vector.at()
(3) 节省空间。
缺点:(1) 在内部进行插入删除操作效率低。
(2) 只能在vector的最后进行push和pop,不能在vector的头进行push和pop。
(3) 当动态添加的数据超过vector默认分配的大小时要进行整体的重新分配、拷贝与释
放
2 list
双向链表
每一个结点都包括一个信息快Info、一个前驱指针Pre、一个后驱指针Post。可以不分配必须的内存大小方便的进行添加和删除操作。使用的是非连续的内存空间进行存储。
优点:(1) 不使用连续内存完成动态操作。
(2)
在内部方便的进行插入和删除操作
(3) 可在两端进行push、pop
缺点:(1) 不能进行内部的随机访问,即不支持[ ]操作符和vector.at()
(2) 相对于verctor占用内存多
3 deque
双端队列 double-end queue
deque是在功能上合并了vector和list。
优点:(1) 随机访问方便,即支持[ ]操作符和vector.at()
(2)
在内部方便的进行插入和删除操作
(3) 可在两端进行push、pop
缺点:(1) 占用内存多
使用区别:
1 如果你需要高效的随即存取,而不在乎插入和删除的效率,使用vector
2 如果你需要大量的插入和删除,而不关心随即存取,则应使用list
3 如果你需要随即存取,而且关心两端数据的插入和删除,则应使用deque
本文主要是使用了STL中德map和set两个容器,使用了它们本身的一些功能函数(包括迭代器),介绍了它们的基本使用方式,是一个使用熟悉的过程。
set(集合)——包含了经过排序了的数据,这些数据的值(value)必须是唯一的。
map(映射)——经过排序了的二元组的集合,map中的每个元素都是由两个值组成,其中的key(键值,一个map中的键值必须是唯一的)是在排序或搜索时使用,它的值可以在容器中重新获取;而另一个值是该元素关联的数值。比如,除了可以ar[43] = "overripe"这样找到一个数据,map还可以通过ar["banana"] = "overripe"这样的方法找到一个数据。如果你想获得其中的元素信息,通过输入元素的全名就可以轻松实现。
map是映射集合中的元素不能重复,set可以进行集合的各种操作(交并补等),当然你也可以用list或vector实现set,但是效率会很低。set一般是用平衡树或哈西表实现的。
映射是一种一一对应的关系,哈西表也可以看作是映射的一种。映射通常可用来实现字典结构(dictionary)
map的基本使用:
#include "stdafx.h"
#include<iostream>
#include<set>
#include<string>
#include<vector>
#include<map>
using namespace std;
int main()
{
//定义map对象
map<string,float> myMap;
myMap["jack"]=98.5;
myMap["bomi"]=98.0;
myMap["Kate"]=97.6;
map<string,float>::iterator itm;
for(itm=myMap.begin();itm!=myMap.end();itm++)
{
//按照键值与映照的数据输出
cout<<(*itm).first<<" : "<<(*itm).second<<endl;
}
int k=0;
cin>>k;
return 0;
}
set的基本使用示例:
#include "stdafx.h"
#include<iostream>
#include<set>
#include<string>
#include<vector>
using namespace std;
int main()
{
set<int> mySet;
mySet.insert(8);
mySet.insert(1);
mySet.insert(12);
mySet.insert(6);
mySet.insert(8); //这里因为前面已经插入了8,重复元素,不会插入。
set<int>::iterator its; //set容器的迭代器
cout<<"正向遍历:"<<" ";
for(its=mySet.begin();its!=mySet.end();its++) //正向遍历
{
cout<<*its<<" ";
}
cout<<endl<<"反向遍历:"<<" ";
set<int>::reverse_iterator rit; //set的逆向迭代器
for(rit=mySet.rbegin();rit!=mySet.rend();rit++)
{
cout<<*rit<<" ";
}
//删除键值为6的元素
mySet.erase(6);
cout<<endl<<"删除之后的反向遍历:"<<" ";
for(rit=mySet.rbegin();rit!=mySet.rend();rit++)
{
cout<<*rit<<" ";
}
//set中元素的检索
mySet.insert(17);
mySet.insert(10);
cout<<endl;
its=mySet.find(10); //使用迭代器来查找,没找到就返回end().
if(its!=mySet.end()) cout<<"找到了"<<*its<<endl;
else cout<<"没有找到查询的元素"<<endl;
its=mySet.find(100);
if(its!=mySet.end()) cout<<"找到了"<<*its<<endl;
else cout<<"没有找到查询的元素"<<endl;
int k=0;
cin>>k;
return 0;
}