map, set, multimap, and multiset

上述四种容器采用红黑树实现,红黑树是平衡二叉树的一种。不同操作的时间复杂度近似为:

插入: O(logN)

查看:O(logN)

删除:O(logN)

hash_map, hash_set, hash_multimap, and hash_multiset

上述四种容器采用哈希表实现,不同操作的时间复杂度为:

插入:O(1),最坏情况O(N)。

查看:O(1),最坏情况O(N)。

删除:O(1),最坏情况O(N)。

记住,如果你采用合适的哈希函数,你可能永远不会看到最坏情况。但是记住这一点是有必要的。
 

几种常见 容器 比较和分析 hashmap, map, vector, list ...hash table

 

转自:http://www.haogongju.net/art/1543058

list支持快速的插入和删除,但是查找费时;

vector支持快速的查找,但是插入费时。

map查找的时间复杂度是对数的,这几乎是最快的,hash也是对数的。 
如果我自己写,我也会用二叉检索树,它在大部分情况下可以保证对数复杂度,最坏情况是常数复杂度,而std::map在任何情况下都可以保证对数复杂度,原因是它保证存诸结构是完全二叉检索树,但这会在存诸上牺牲一些时间。

STL   中的   map   内部是平衡二叉树,所以平衡二叉树的性质都具备。查找数据的时间也是对数时间。 vector,在分配内存上一般要比   new   高效的多。

为什么说   hash_map   是对数级的?在不碰撞的情况下,hash_map是所有数据结构中查找最快的,它是常数级的。 
如果对问题设计了足够好的hash算法,保证碰撞率很低,hash_map的查找效率无可置疑。 
另外,STL的map,它的查找是对数级的,是除hash_map外最高的了,你可以说“也许还有改进余地”,但对于99.9999%的程序员,设计一个比STL   map好的map,我执悲观态度。 
STL的map有平衡策略(比如红黑树什么的),所以不会退化,不需要考虑数据本身的分布问题。只不过,如果数据本身是排好序的,用vector或heap会明显的快些,因为它们的访问比较简单。

我想没必要怀疑stl::map的查找效率,影响效率最主要的因素是什么?算法,在查找问题上,有什么算法比RB_tree更好吗?至少现在还没有。不否 认你可以通过自己写代码,设计一个符合你需要的BR—TREE,比stl::map简捷那么一点,但最多也就每次迭代中少一行指令而已,处理十万个数据多 执行十万行指令,这对你重要吗?如果你不是在设计OS像LINUX,没人会关注这十万行指令花的时间。 
rb-tree的时间花在了插入和删除上,如果你不是对插入和删除效率要求很高,你没有理由不选择基于rb-tree的stl::map。

大多数程序员写不出比std::map更好的map,这是当然的。然而并不是std::map的所有特性都出现在我们的程序中,自己编写的可以更适合自己的程序,的确会比std::map更快一些。

关于hash_map,它与map的实现机制是不一样的,map内部一般用树来实现,其查找操作是O(logN)的,这个没有争议,我就不多说了。 
hash_map的查找,内部是通过一个从key到value的运算函数来实现的,这个函数“只接受key作为参数”,也就是说,hash_map的查找 算法与数据量无关,所以认为它是O(1)级的。来这里的应该都是达人,可以参看《数据结构》。当然,事实总不这样完美,再引一段前面我自已说的话,进一步 说明,以免误会:

----------------------------------------- 
在不碰撞的情况下,hash_map是所有数据结构中查找最快的,它是常数级的。 
------------------------------------------ 
注意我的前提:“在不碰撞的情况下”,其实换句话说,就是要有足够好的hash函数,它要能使key到value的映射足够均匀,否则,在最坏的情况下,它的计算量就退化到O(N)级,变成和链表一样。 
如果说   hash_map   是所有容器中最慢的,也只能说:“最拙劣的hash函数”会使hash_map成为查找最慢的容器。但这样说意义不大,因为,最凑巧的排列能使冒泡排序成为最快的排序算法。

BS: "对于大型容器而言,hash_map能够提供比map快5至10倍的元素查找速度是很常见的,尤其是在查找速度特别重要的地方.另一方面,如果hash_map选择了病态的散列函数,他也可能比map慢得多. "

ANSIC++在1998年之后就没再有重大改变,并且决定不再向C++标准库中做任何重大的变更,正是这个原因,hash   table(包括hash_map)并没有被列入标准之中,虽然它理应在C++标准之中占有一席之地。 
虽然,现在的大多数编译平台支持hash   table,但从可移植性方面考虑,还是不用hash   table的好。

hehe俺也来凑凑热闹。 
1.有的时候vector可以替代map 
比如key是整数,就可以以key的跨度作为长度来定义vector。 
数据规模很大的时候,差异是惊人的。当然,空间浪费往往也惊人。 
2.hash是很难的东西 
没有高效低碰撞的算法,hash_xxx没有意义。 
而对不同的类型,数据集,不可能有优良的神仙算法。必须因场合而宜。 
俺有的解决方法是GP,可不是饭型,是遗传编程,收效不错。

你的百万级的数据放到vector不大合适。因为vector需要连续的内存空间,显然在初始化这个容器的时候会花费很大的容量。 
使用map,你想好了要为其建立一个主键吗?如果没有这样的需求,为什么不考虑deque或者list? 
map默认使用的是deque作为容器。其实map不是容器,拿它与容器比较意义不大。因为你可以配置它的底层容器类型。

如果内存不是考虑的问题。用vector比map好。map每插入一个数据,都要排序一次。所以速度反不及先安插所有元素,再进行排序。

用 binary_search对已序区间搜索,如果是随机存取iterator,则是对数复杂度。可见,在不考虑内存问题的情况下,vector比map 好。

如果你需要在数据中间进行插入,list 是最好的选择,vector   的插入效率会让你痛苦得想死。

涉及到查找的话用map比较好,因为map的内部数据结构用rb-tree实现,而用vector你只能用线性查找,效率很低。

stl还提供了 hash容器,理论上查找是飞快~~~。做有序插入的话vector是噩梦,map则保证肯定是按key排序的,list要自己做些事情。

HASH类型的查找肯定快,是映射关系嘛,但是插入和删除却慢,要做移动操作, LIST类型的使链式关系,插入非常快,但是查找却费时,需要遍历~~ , 还是用LIST类型的吧,虽然查找慢点,

先快速排序,然后二分查找,效率也不低

C++ STL中常见容器的时间复杂度和比较和分析的更多相关文章

  1. 【转】C++ STL中常见容器的时间复杂度

    map, set, multimap, and multiset 上述四种容器采用红黑树实现,红黑树是平衡二叉树的一种.不同操作的时间复杂度近似为: 插入: O(logN) 查看:O(logN) 删除 ...

  2. C++ STL 中 map 容器

    C++ STL 中 map 容器 Map是STL的一个关联容器,它提供一对一(其中第一个可以称为关键字,每个关键字只能在map中出现一次,第二个可能称为该关键字的值)的数据 处理能力,由于这个特性,它 ...

  3. STL中常用容器及操作 学习笔记1

    @[TOC](下面介绍STL中常见的容器及操作)## 不定长数组 vector> vetcor:其实就是一个数组或者说是容器 其操作不同于之前直接定义的数组 > 而且可以直接赋值也可以直接 ...

  4. STL中的容器介绍

    STL中的容器主要包括序列容器.关联容器.无序关联容器等. 一]序列容器 (1) vector vector 是数组的一种类表示,提供自动管理内存的功能,除非其他类型容器有更好满足程序的要求,否则,我 ...

  5. [C++]STL中的容器

    C++11 STL中的容器 一.顺序容器: vector:可变大小数组: deque:双端队列: list:双向链表: forward_list:单向链表: array:固定大小数组: string: ...

  6. STL中的容器

    STL中的容器 一. 种类: 标准STL序列容器:vector.string.deque和list. 标准STL关联容器:set.multiset.map和multimap. 非标准序列容器slist ...

  7. 算法求解中的变量、数组与数据结构(STL 中的容器)

    本质上算法都是对数据的操作,没有数据,没有存储数据的容器和组织方式,算法就是无源之水无本之木,就是巧妇也难为无米之炊.算法是演员,变量.数组.容器等就是舞台, 然后整个算法的处理流程,都是针对这些数据 ...

  8. STL中的容器作为返回值

    分别以函数返回值方式和参数传引用方式测试了vector.map两种容器,代码如下: // testContainer.cpp : Defines the entry point for the con ...

  9. C++STL中map容器的说明和使用技巧(杂谈)

    1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自 ...

随机推荐

  1. selenium常用的API(一)截屏

    我们在使用selenium测试过程中,可使用截屏功能将用例执行失败的画面截图保存,方便测试执行结束后查看并定位问题. 以下介绍两种截屏方法: 对当前浏览器窗口截屏 使用selenium自带的get_s ...

  2. 远程连接Linux mysql报错:Access denied for user ‘root’@‘localhost’(using password: YES)的解决方法

    在新安装好的Centos7上刚安装好mysql,准备进去看看,但是登陆的时候,发现报错啦: ERROR 1045 (28000): Access denied for user 'root'@'loc ...

  3. 【爬虫】大杀器——phantomJS+selenium

    [爬虫]大杀器——phantomJS+selenium 视频地址 江湖上有一个传说,得倚天屠龙者可称霸武林.爬虫中也有两个大杀器,他们结合在一起时,无往不利,不管你静态网站还是动态网站,通吃. pha ...

  4. BurpSuite Intruder模块匹配返回包内容

    很多时候burpsuite intruder爆破我们是看返回包的长度,那么如何根据返回包的内容来做筛选呢? 这里我用的本地某cms环境做个演示 Intruder模块怎么用的不用介绍了吧 直接进入正题 ...

  5. C语言定义结构体指针数组并初始化;里面全是结构体的地址

    #include <stdio.h> #include <string.h> struct tells;//声明结构体 struct info { char *infos; } ...

  6. 题解 CF1097F 【Alex and a TV Show】

    妙妙题-- 这道题这要求%2的个数,肯定有什么性质 于是我们想到了用\(bitset\)来处理 由于三操作有\(gcd\),于是我们又想到用反演来解决 我们回忆一下反演的柿子 设\(f(x)\)为x出 ...

  7. VMware安装VMwaretools

    默认点击“安装VMware Tools(T)”选项下载好安装包 下载的安装包放在计算机的media目录下 进入/media/ubuntu14-04/VMware Tools目录: cd /media/ ...

  8. 数据结构实验之查找二:平衡二叉树 (SDUT 3374)

    #include <stdio.h> #include <string.h> #include <stdlib.h> struct node { int data; ...

  9. TCP四路挥手问题:

    1.不管被动和主动,只要发送Fin分节就关闭此端应用层.那么挥手时S接到Fin,此刻C已经关闭应用层,那么S再发送消息岂不是无用,浪费网络资源?

  10. Mybatis mapper接口与xml文件路径分离

    为什么分离 对于Maven项目,IntelliJ IDEA默认是不处理src/main/java中的非java文件的,不专门在pom.xml中配置<resources>是会报错的,参考这里 ...