hash_map

hash_map:
总结:http://blog.csdn.net/dodolzg/article/details/6381978
引入目的:
hash_map基于hash table(哈希表)。 哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间;而代价仅仅是消耗比较多的内存。

原理:
hash_map,首先分配一大片内存,形成许多桶。是利用hash函数,对key进行映射到不同区域(桶)进行保存。

插入过程是:
1、得到key ,通过hash(key)函数得到对应key的hash值 
2、存放key和value在对应hash值的桶内。 
取值过程是:
1、给出key,通过hash(key)函数得到hash值 
2、比较对应hash值的桶内元素是否与key相等,若都不相等,则没有找到。 否则取出相等记录的value。

——可以看出,hash和比较两个操作是hash_map的重点。 

与map区别在于:
(1)构造函数。hash_map需要hash函数,等于函数;map只需要比较函数(小于函数). 
(2)存储结构。hash_map采用hash表存储,map一般采用红黑树(RB Tree)实现。因此其memory数据结构是不一样的。 

权衡是否使用hash_map:
权衡三个因素: 查找速度(注意还有hash的时间), 数据量, 内存使用。

常用函数:
(1)hash_map(size_type n) 如果讲究效率,这个参数是必须要设置的。n 主要用来设置hash_map 容器中hash桶的个数。桶个数越多,hash函数发生冲突的概率就越小,重新申请内存的概率就越小。n越大,效率越高,但是内存消耗也越大。 
(2)const_iterator find(const key_type& k) const. 用查找,输入为键值,返回为迭代器。 
(3)data_type& operator[](const key_type& k) . 当你使用[key ]操作符时,如果容器中没有key元素,这就相当于自动增加了一个key元素。因此当你只是想知道容器中是否有key元素时,你可以使用find。如果你希望插入该元素时,你可以直接使用[]操作符。 
(4)insert 函数。在容器中不包含key值时,insert函数和[]操作符的功能差不多。但是当容器中元素越来越多,每个桶中的元素会增加,为了保证效率,hash_map会自动申请更大的内存,以生成更多的桶。因此在insert以后,以前的iterator有可能是不可用的。 
(5)erase 函数。在insert的过程中,当每个桶的元素太多时,hash_map可能会自动扩充容器的内存。但在sgi stl中是erase并不自动回收内存。因此你调用erase后,其他元素的iterator还是可用的。

应用例子:

#include <ext/hash_map>
#include <string>
#include <iostream>

using namespace std;
using namespace __gnu_cxx;

class A{
    public:
        A(string a):m_a(a){}
        string getValue() const{return m_a;}
    private:
        string m_a;
};

struct hash_A{
    bool operator() (const A& s)const{
        return (s.getValue())[0]-'a';
    }
};
struct equal_A{
    bool operator() (const A& s1, const A& s2)const{
        return s1.getValue()==s2.getValue();
    }
};

int main(){
    hash_map<A, int, hash_A, equal_A> mymap;
    A a1("mother"), a2("father");
    mymap[a1] = 50;
    mymap[a2] = 51;
    
    cout << mymap[a1] << endl;
    hash_map<A, int, hash_A, equal_A>::iterator iter; 
    for(iter=mymap.begin();iter!=mymap.end();iter++)
        cout << (*iter).first.getValue() << " " << (*iter).second << endl;

    if(mymap.find(a1)!=mymap.end()){
        cout << "find!" << endl;
        mymap.erase(a1);
    }
    if(mymap.find(a1)!=mymap.end())
        cout << "find!" << endl;
    else
        cout << "missing!" << endl;
    
    mymap.insert(pair<A,int>(a1,50));
    
    cout << mymap.size() << endl;
    
    system("pause");
    return 0;
    
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值