您的位置:首页 > 其它

关于容器操作

2014-01-01 15:49 190 查看
容器是编程的基本工具之一,基本上所以场合都要使用!搞清楚他们的使用复杂度,正确使用合适的容器,更加有利于优化程序。

vector:典型的序列容器,C++标准严格要求此容器的实现内存必须是连续的,唯一可以和标准C兼容的STL容器,任意元素的读取、修改具有常数事件复杂度,在序列尾部进行插入、删除是常数事件复杂度,但在序列的头部插入、删除的时间复杂度是O(n),可以在任何位置插入新元素,有随机访问的功能,插入删除操作需要做考虑。

deque(双端队列,double-ended-queue):序列容器,内存也是连续的,和vector相似,区别在于它可以在头和尾都可以进行插入和删除操作,并且都是常数事件复杂度,支持随机访问功能,任何位置的表操作功能时间复杂度为O(n)。

list:序列容器,内存是不连续的,任意元素的访问、修改时间复杂度度O(n),插入、删除操作是常数时间复杂度,可以在任何位置插入新元素。

set:关联容器,内部元素不容许重复,数据被自动组织成一棵红黑树,查找速度很快,时间复杂度为O(logn)。

map:关联容器,内部形式为{键,值},键值不能重复,内部结构和set一样,都是一棵红黑树,查找速度很快,时间复杂度为O(logn)。

容器按照容器分类

连续内存容器:这种类型的容器主要是数组、vector、deque。特点是在一块连续的内存块上存放数据,所以有数据插入或删除的时候,如果不是在序列的或者两端那么花费的代价是非常大的,因为需要保证连续内存,同时给新元素腾出空间或者填充删除元素的空间,如果存储的是复杂结构的话就要花费大量的事件进行拷贝操作。

基于节点的容器:这类容器是list、set(multiset)、map(multimap),这类容器中的数据被随机存储在系统分配的内存块中,可能是连续的也可能不是连续的。这样的容器在插入或者删除的时候修改的只是节点的指针,这样消耗时间和空间都非常小。

各种容器使用情况

一、如果需要不断添加成员,最好还是使用list和deque容器。如果数据复杂可以使用set和map,vector是不能用了,因为vector在添加元素的时候,因为他的内存是一定的,如果添加新成员,就需要申请空间,他不是一个一个申请,而是空间不足就申请一块当前容量的2倍新的内存空间,然后把所有成员都拷贝到新空间中,花费很惊人,如果不断添加新成员,花费就更大了!如果由于某些原因必须使用vector,并且需要大量添加新元素,那么建议申请一个大的内存,这样就可以减少很多不必要的消耗。list和deque就比较好都是常数添加新元素,我说的是从前或者从后插入。

二、快速查找

这需要看容器内成员的排列情况,也需要看你动用的是那种算法!对于已经排序的序列容器,使用binary_search、lower_bound、upper_bound、equal_range可以获得对数时间复杂度的查找速度(OlogN),未排序的序列容器只能用线性查找,复杂度O(n);对于关联容器,其内部是一棵标准的红黑树,总是查找效率是O(logN),因为关联容器总是按照键值排序的。

三、表操作(就是删除和添加操作)

只有list操作的时间复杂度是常数。vector表操作比较复杂,一是找位置,二是申请空间。操作比较多!deque如果只是从容器头或者尾部插入他的时间复杂度为常数,如果中间插入复杂度为O(n),对于map和set时间复杂度为logn。

四、各种容器的优缺点

对每个容器都熟悉,了解他们的特点才能更好的应用他们,选择的时候就能更轻松。

vector的数据模型就是数组的延伸。支持高效随机访问、节省空间,内存与C完全兼容。

缺点:内部表操作需要申请大量内存和大量拷贝工作。

list:是链表,需要就申请一块内存,不需要可以快速删除

优点:可以任意位置插入删除成员,时间复杂度为常数。两个容器融合也是常数时间复杂度

缺点:不支持随机访问、比vector占用更多的存储空间。

deque是数组和链表的组合情况,首先支持高效随机访问。内部插入删除成员,主要是可以两端进行push和pop

缺点:内存占用比较高

关联容器:内部都是红黑树 元素会按照键值排序、查找对数时间复杂度、通过键值查成员值。

五、综合应用

如果需要随机访问,并且内部成员固定vector不二人选。

需要任意位置随机插入删除,用list

对于顺序插入和删除的的操作(主要是尾部插入,头部删除的)用deque或者queue,queue队列应用还是比较多的。

如果成员结构复杂,并且需要不断查找,就是需要有关键字查找用map和set
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: