详解STL中的map和hash_map区别

本文详细介绍了STL中的map和hash_map的区别。map底层基于红黑树,查询时间复杂度为log(n),而hash_map使用hash表,查询时间复杂度接近O(1)。选择使用哪种容器取决于具体应用场景,考虑查找效率和内存消耗。hash_map虽查找速度快,但内存消耗大,适用于大量记录的快速查询,而map在内存敏感的场景下更合适。
摘要由CSDN通过智能技术生成


在网上看到有关STL中hash_map的文章,以及一些其他关于STL map和hash_map的资料,总结笔记如下:
    1、STL的map底层是用红黑树实现的,查找时间复杂度是log(n);
    2、STL的hash_map底层是用hash表存储的,查询时间复杂度是O(1);
    3、什么时候用map,什么时候用hash_map?
    这个药看具体的应用,不一定常数级别的hash_map一定比log(n)级别的map要好,hash_map的hash函数以及解决地址冲突等都要耗时间,而且众所周知hash表是以空间换时间的,因而hash_map的内存消耗肯定要大,一般情况下,如果记录非常大,考虑hash_map,查找效率会高很多,如果要考虑内存消耗,则要谨慎使用hash_map。
    以下内容来自:http://blog.163.com/liuruigong_lrg/blog/static/27370306200711334341781/
 
0. 为什么需要hash_map
    用过map吧,map提供一个很常用的功能,那就是提供key-value的存储和查询功能。例如,我要记录一个人名和相应的存储,而且随时增加,要快速查找和修改:
    岳不群-华山派掌门人,人称君子剑
    张三丰-武当掌门人,太极拳创始人
    东方不败-第一高手,葵花宝典
    .......
    这些信息如果保存下来并不复杂,但是找起来比较麻烦。例如我要找“张三丰”的信息,最笨的方法就是取得所有的记录,然后按照名字一个一个比较。如果要速度快,就需要把这些记录按照字母顺序排列,然后按照二分查找。但是增加记录的时间同时需要保持记录有序,因此需要插入排序。考虑到效率,这就需要用二叉树。如果你使用STL中map容器,你可以非常方便实现这个功能,而不用关心其他细节。看看map的实现。

map<string, string> namemap;
 
2. 

3. //增加。。。

4. namemap["岳不群"]="华山派掌门人,人称君子剑";

5. namemap["张三丰"]="武当掌门人,太极拳创始人";

6. namemap["东方不败"]="第一高手,葵花宝典";

7. ...

8. 

9. //查找。。

10. if(namemap.find("岳不群") != namemap.end())

11. {

12.         ...

13. } 


实现起来比较容易,而且效率很高,100万条记录,最多也只要20次的string.compare的比较,就能找到你要找的记录。
    速度永远满足不了现实的需求,如果100万条记录,需要频繁的进行搜索时,20次比较也会成为瓶颈,要是能降到一次或者两次比较是否有可能?而且当记录数到200万的时候也是一次或二次比较,是否有可能?而且还需要和map一样的方便使用。
    答案是肯定的,这时你需要has_map。虽然hash_map目前没有纳入C++标准模板库中,但几乎每个版本的STL都提供了相应的实现。而且应用十分广泛。在正式使用hash_map之前,先看看hash_map的原理。

1、数据结构:hash_map原理
    hash_map基于hash table(哈希表)。哈希表最大的优点是:把数据存储和查询消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。然后在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的。另外,编码比较容易也是它的特点之一。
    其基本原理是:使用一个下标范围比较大的数组来存储元素。可以设计一个函数(哈希函数ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值