Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1413947
  • 博文数量: 241
  • 博客积分: 10
  • 博客等级: 民兵
  • 技术积分: 2253
  • 用 户 组: 普通用户
  • 注册时间: 2012-04-11 22:27
个人简介

--

文章分类

全部博文(241)

文章存档

2021年(3)

2019年(6)

2018年(1)

2017年(9)

2016年(21)

2015年(50)

2014年(125)

2013年(26)

我的朋友

分类: C/C++

2014-03-07 11:33:31

1、分类
顺序容器:vector、deque、list
关联容器:set、multiset、map、multimap

2、顺序容器

2.1 vector
(1)简介
    线性顺序结构,和数组类似,但是大小可以不预先设定,并且自动扩展。它可以像数组一样被操作,由于它的特性我们完全可以将vector 看作动态数组。
    在创建一个vector 后,它会自动在内存中分配一块连续的内存空间进行数据存储,初始的空间大小可以预先指定也可以由vector 默认指定,这个大小即capacity ()函数的返回值。当存储的数据超过分配的空间时vector 会重新分配一块内存块,但这样的分配很耗时,在重新分配空间时它会做这样的动作:  首先,vector 会申请一块更大的内存块;  然后,将原来的数据拷贝到新的内存块中;  其次,销毁掉原内存块中的对象(调用对象的析构函数);  最后,将原来的内存空间释放掉。  
如果vector 保存的数据量很大时,这样的操作一定会导致糟糕的性能(这也是vector 被设计成比较容易拷贝的值类型的原因)。所以说vector 不是在什么情况下性能都好,只有在预先知道它大小的情况下vector 的性能才是最优的。

2)特点  
1) 指定一块如同数组一样的连续存储,但空间可以动态扩展。即它可以像数组一样操作,并且可以进行动态操作。通常体现在push_back() pop_back() 。 
2) 随机访问方便,它像数组一样被访问,即支持[ ] 操作符和vector.at() 
3) 节省空间,因为它是连续存储,在存储数据的区域都是没有被浪费的,但是要明确一点vector 大多情况下并不是满存的,在未存储的区域实际是浪费的。  
4) 在内部进行插入、删除操作效率非常低,这样的操作基本上是被禁止的。Vector 被设计成只能在后端进行追加和删除操作,其原因是vector 内部的实现是按照顺序表的原理。 
5) 只能在vector 的最后进行push 和pop ,不能在vector 的头进行push 和pop 。 
6) 当动态添加的数据超过vector 默认分配的大小时要进行内存的重新分配、拷贝与释放,这个操作非常消耗性能。 所以要vector 达到最优的性能,最好在创建vector 时就指定其空间大小。

(3)使用方法  
包含头文件   #include
1)创建 
vector vt;//创建空的vector
vector vt(n); //创建包含3个默认为0的元素
vector vt(m,n);//创建m个n的元素的vector
vector vt(vt2);//vt2拷贝到vt
vector vt(vt2.begin(),vt2.end());//将vt2指定范围内元素拷贝到vt

vt2.assign(vt.begin(),vt.end());//vt拷贝到vt2
vt2.assign(int num,value);vt2初始化为num个value

2)增
vt.push_back(n);//尾部添加n

iterator vt.insert(iterator location, value);location前插入value,返回该元素迭代器
vt.insert(iterator location, int num,value);;location前插入num个value
vt.insert(iterator location,iterator start,iterator end);location前插入start到end之间的内容

3)删
vt.clear();//删除所有

vt.erase(iterator location);删除location处的元素
vt.erase(iterator start,iterator end);删除从start到end之间的元素

vt.pop_back();删除最后一个元素

4)改
vt.at[n] = value;
vt.resize(); 重置容器大小
vt[] = value

vt.swap(vector vt2); vt2和vt互相交换

5) 查
vt.begin() vt.end();首尾迭代器
vt.rbegin() vt.rend();反向首尾迭代器
vt.front() vt.back(); 首尾元素

vt[];
vt.at(n);类似数组下标操作

vt.size();查容器大小,如果没初始化为0,所以没有制定vector大小的,不要使用vt[i],而是用push_back()
vt.capacity();容器容量
bool vt.empty();是否为空,返回true为空

2.2 list  
(1)简介  
是一个线性链表结构,它的数据由若干个节点构成,每一个节点都包括一个信息块(即实际存储的数据)、一个前驱指针和一个后驱指针。它无需分配指定的内存大小且可以任意伸缩,这是因为它存储在非连续的内存空间中,并且由指针将有序的元素链接起来。 

(2)特点 
1) 不使用连续的内存空间这样可以随意地进行动态操作; 
2) 可以在内部任何位置快速地插入或删除,当然也可以在两端进行push和pop  。  
3) 不能进行内部的随机访问,即不支持[ ] 操作符和vector.at()  ; 
    Lists将元素按顺序储存在链表中,与向量(vectors)相比,它允许快速的插入和删除,但是随机访问却比较慢.   

(3)使用方法 
增加 的方法:
list.push_front(n);前面添加n
list.opo_front();删除前面的一个元素

两链表合并:
list_one.merge(list_two);//将两有序链表合并为有序链表,放到list_one ,释放list_two,,必须是有序,且如有重复也会排序成重复
c1.merge(c2,comp)      合并2个有序的链表并使之按照自定义规则排序之后从新放到c1中,释放c2。comp必须和c1、c2排序一致。
c1.splice(c1.beg,c2)      将c2连接在c1的beg位置,释放c2
c1.splice(c1.begin(),c2,c2.begin())      将c2的begin位置的元素连接到c1的begin位置,并且在c2释放掉begin位置的元素
c1.splice(c1.beg,c2,c2.beg,c2.end)      将c2的[beg,end)位置的元素连接到c1的beg位置并且释放c2的[beg,end)位置的元素

删除:
remove(num)             删除链表中匹配num的元素。
remove_if(comp)       删除条件comp为真的元素,参数为自定义的回调函数。
list.reverse()       反转链表
list.unique()       删除相邻相同的的元素仅保留一个

排序:
c.sort()       将链表排序,默认升序
c.sort(comp)       自定义回调函数实现自定义排序
降序排序的cmp函数如下所示:
bool cmp(int x, int y)
{
return x>y;
}

减少的:不能随机访问[] .at()

2、3 deque 
(1)简介 
是一种优化了的、对序列两端元素进行添加和删除操作的基本序列容器。它允许较为快速地随机访问,但它不像vector 把所有的对象保存在一块连续的内存块,而是采用多个连续的存储块,并且在一个映射结构中保存对这些块及其顺序的跟踪。向deque  两端添加或删除元素的开销很小。它不需要重新分配空间,所以向末端增加元素比vector 更有效。   实际上,deque  是对vector 和list  优缺点的结合,它是处于两者之间的一种容器。   

(2)特点 
1) 随机访问方便,即支持[ ]  操作符和vector.at()  ,但性能没有vector 好; 
2)  可以在内部进行插入和删除操作,但性能不及list  ; 
3)  可以在两端进行push  、pop  ; 
4)  相对于verctor 占用更多的内存。 
双向队列和向量很相似,但是它允许在容器头部快速插入和删

(3)使用方法 
较vector增加push_front() pop_front()方法

2、4 总结 
    vector 是一段连续的内存块,而deque 是多个连续的内存块,  list  是所有数据元素分开保存,可以是任何两个元素没有连续。   
vector 的查询性能最好,并且在末端增加数据也很好,除非它重新申请内存段;适合高效地随机存储。   
list  是一个链表,任何一个元素都可以是不连续的,但它都有两个指向上一元素和下一元素的指针。所以它对插入、删除元素性能是最好的,而查询性能非常差;适合大量地插入和删除操作而不关心随机存取的需求。   
deque  介于两者之间,兼顾数组和链表的优点,它是分块的链表和多个数组的联合。所以它有被list好的查询性能,有比vector好的插入、删除性能。 
如果你需要随机存取又关心两端数据的插入和删除,那么deque是最佳之选。 

阅读(807) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~