关于容器操作
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
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
相关文章推荐
- 关于c++顺序容器小结(二)---基本操作
- 关于list容器与vector容器中的erase操作
- 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种
- 关于c++ list容器的操作摸索
- 关于在spring 容器初始化 bean 和销毁前所做的操作的3种方式
- 关于C++ 容器的swap操作
- 关于以string类型的容器,容器中字符串的操作
- 关于容器的各种操作
- 关于容器map的操作代码
- 关于在spring 容器初始化 bean 和销毁前所做的操作定义方式有三种
- 用NPOI操作EXCEL关于HSSFClientAnchor(dx1,dy1,dx2,dy2,col1,row1,col2,row2)的参数
- 【Docker安全】关于Docker使用root与非root用户的场景中的容器与host中的执行用户的研究
- 详解IIS中的重写工具下关于操作重定向URL中的{R:N}与{C:N}使用介绍
- C++标准库(STL)之vector容器的使用(包括特点、初始化、遍历与常用操作)
- 关于锚点跳转及jQuery下相关操作与插件
- 关于sqlite3使用操作中内存耗尽导致进程被kill的问题
- 在SQL中关于时间日期的操作
- STL顺序容器操作7
- 关于C#里面SQLite读取数据的操作
- Oracle关于时间/日期的操作