STL源码解析-05关联容器-02hash

**************************************
hashtable将元素通过hash函数,转化为一定空间内的关键字,方便查找。
在映射过程中,不同的值可能会影射到相同的关键字,这时需要解决该碰撞问题,方法有:
线性检测,检测到冲突,循序往下一一查找,这样的话,有可能每个元素都需要一一查找空闲空间,导致平均插入成本很高,这种现场成为主集团。
二次检测,H+1^2,H+2^2,按照这样的顺序查找空闲空间,为了提高效率,后一个H可由前一个H加上一个数,
如果两个数的哈希值一样,二次检测的结果也一样,这成为次集团。
开链:一个键后面跟着一个list。STL中的hashtable就是这种方式。
*
*
STL中的hash迭代器,是一种forward迭代器,只能+。有指向当前节点的指针和指向对应的vector的指针。
*
*
hashtable结构:
还有一个vector,每个元素都指向一个链表。在STL中定义了28个质数,hashtable根据实际的数值,取接近的质数以分配vector的大小,
当现有的节点数>vector的size时,会重新分配vector。
insert分为insert_unique和insert_equal操作,前者保证插入的数不能有重复,后者可以插入键值相同的数。可以先用unique之后再用equal。
insert_unique:先调用resize函数,看是否需要增大vector,然后插入,vector的索引通过取余得到。
resize:如果已有元素的个数大于vector的size,需要根据得到的最新质数,分配新的空间,将在旧空间的元素,重新计算hash,
复制到新的空间,最后旧空间与新空间swap一下即可。
insert_equal:也是先调用resize,遍历找到和他相同的节点,在该节点的前面插入。
clear:删除每一个节点,vector的内容为null,个数置零。
*
 
#include <iostream>
#include <algorithm>
#include <ext/hash_set>
 
using namespace __gnu_cxx;
using namespace std;
 
int main()
{
//hashtable<value, key, hash_func, extract-key, equal_key, allocator>
//hash_func:hash函数,STL中定义了一下哈希函数,基本啥也没干,基本上都直接返回其值。
//extract-key:从节点中取出键值的方法,对于不同的对象自己提供。
//eqaulkey:判断键值相同与否的方法。
    hashtable<int, int, hash<int>, _Identity<int>, equal_to<int>, allocator<int> > iht(50,hash<int>(), equal_to<int>());
 
cout << iht.size() << endl;//0
cout << iht.bucket_count() << endl;//53,最接近的质数
cout << iht.max_bucket_count() << endl;//定义的最大的质数
 
iht.insert_unique(59);
iht.insert_unique(3);
iht.insert_unique(23);
iht.insert_unique(4);
iht.insert_unique(11);
iht.insert_unique(88);
 
cout << iht.size() << endl;//6
 
hashtable<int, int, hash<int>, _Identity<int>, equal_to<int>, allocator<int> >::iterator ite = iht.begin();
for (int i=0; i<iht.size(); i++,ite++)//ite是forward迭代器,只能+
cout << *ite << "";
cout << endl;
 
for(int i=0; i<48;i++)
iht.insert_equal(i);
 
cout << iht.max_bucket_count() << endl;//不变
cout << iht.bucket_count() << endl;//超过了vector的容量53,revise,设置新的大小为97
 
cout << *(iht.find(4)) << endl;//第一个4的迭代器。
cout << iht.count(4) << endl;
 
return 0;
}
 
*
hash_set:与set的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
hash_map:与map的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
hash_multimap:与multimap的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
hash_multiset:与multiset的用法一样,底层是hashtable实现,默认vector大小是100,唯一不同是不排序。
*
posted @ 2011-12-02 15:22  magicdog  阅读(306)  评论(0)    收藏  举报