hash
c++2.0之前,C++里面没有hashtable,c++2.0后引入了相关容器,比如std::unordered_set
std::unordered_multiset
std::unordered_map
std::unordered_multimap
这些容器中都使用了hashtable。
1 hashtable结构
hashtable使用开链法解决冲突,hashtable的节点如下:
template < class _Va l>
struct _Hashtable_node
{
_Hashtable_node* _M_next;
_Val _M_val;
};
2 hashtable实现
2.1 hashtable的大小
STL提供了28个素数作为hashtable的大小,__stl_next_prime数组,提供最接近n且比n要大的素数。
enum { __stl_num_primes = 28 };
static const unsigned long __stl_prime_list[__stl_num_primes] =
{
53ul, 97ul, 193ul, 389ul, 769ul,
1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
1610612741ul, 3221225473ul, 4294967291ul
};
2.2 hash函数
hash函数在c++2.0后已经有实现了,对各种基本数据类型都是支持的。
#include <iostream>
#include <functional>
int main()
{
unsigned long hashCode = std::hash<int>()(100); //100
std::cout << hashCode << std::endl;
hashCode = std::hash<long>()(100); //100
std::cout << hashCode << std::endl;
hashCode = std::hash<std::string>()(std::string("AbC")); //9987680454171677922
std::cout << hashCode << std::endl;
hashCode = std::hash<const char*>()("AbC"); //4198855
std::cout << hashCode << std::endl;
hashCode = std::hash<char>()('a'); //97
std::cout << hashCode << std::endl;
hashCode = std::hash<float>()(1.234567); //3634307559811082653
std::cout << hashCode << std::endl;
hashCode = std::hash<double>()(1.234567); //9197035831012427150
std::cout << hashCode << std::endl;
void* t = (void*)(new int(100));
hashCode = std::hash<void*>()(t); // 28327984
std::cout << hashCode << std::endl;
return 0;
}
运行后结果为:
100
100
9987680454171677922
4198855
97
3634307559811082653
9197035831012427150
28327984