hashtable
就是散列表(哈希表)
哈希表采用散列技术,散列技术是一种查找技术,而且是一种"一步到位"的查找技术
散列技术存储元素的时候是按照函数f对应的规律来存储元素,使得我们存储元素的位置为f(key)
顺序/二分/差值查找:要查找元素key->与待查找集合中的元素对比->找到要查找元素的位置index
散列查找:要查找元素key->直接通过函数f计算出要查找元素的位置index
hashtable
最开始只有53个桶,当元素个数大于桶的个数时,桶的数目扩大为最接近当前桶数两倍的质数,实际上,桶数目的增长顺序被写死在代码里:
static const unsigned long __stl_prime_list[__stl_num_primes] = {
53, 97, 193, 389, 769, 1543, 3079, 6151, 12289, 24593,
49157, 98317, 196613, 393241, 786433, 1572869, 3145739,
6291469, 12582917, 25165843, 50331653, 100663319,
201326611, 402653189, 805306457, 1610612741,
3221225473ul, 4294967291ul};
template<class Value, //节点的实值类别
class Key, //节点的键值类别
class HashFcn, //hash function的函数类别
class ExtractKey, //从节点中取出键值的方法(仿函数)
class EqualKey, //判断键值是否相同(仿函数)
class Alloc=alloc> //空间配置器
class hashtable {
public:
typedef HashFcn hasher;
typedef EqualKey key_equal;
typedef size_t size_type;
private:
hasher hash;
key_equal equals;
ExtractKey get_key;
typedef __hashtable_node<Value> node;
vector<node*, Alloc> buckets; // 保存桶的vector
size_type num_elements;
public:
size_type bucket_count() const { return buckets.size(); }
};
// 节点
template<class Value>
struct __hashtable_node {
__hashtable_node *next;
Value val;
};
// 迭代器
template<class Value, class Key, class HashFen, class ExtractKey, class EqualKey, class Alloc>
struct __hashtable_iterator {
node *cur;
hashtable *ht;
};
hashtable<pair<const string, int>,
string,
hash<string>,
select1st<pair<const string, int>>,
equal_to<string>,
alloc> siht(100, hash<string>(), equal_to<string>());
cout << siht.size() << endl; // 0
cout << siht.bucket_count() << endl; // 193
siht.insert_unique(make_pair(string("jjhou"), 95));
siht.insert_unique(make_pair(string("sabrina"), 90));
siht.insert_unique(make_pair(string("mjchen"), 85));
cout << siht.size() << endl; // 3
cout << siht.bucket_count() << endl; // 193
cout << siht.find(string("sabrina"))->second << endl; //90
cout << siht.find(string("jjhou"))->second << endl; //95
cout << siht.find(string("mjchen"))->second << endl; //85
#include
#include
using namespace std;
int main()
{
//hash_table
//
//note: hash_table has no default ctor
hashtable<int, int, hash<int>, identity<int>, equal_to<int>, alloc>
iht(50, hash<int>, euqal_to<int>); //指定50个buckets
cout << iht.size() << endl; //0
cout << iht.bucket_count() << endl; //53
cout << iht.max_bucket_count() << endl; // 4294967291
iht.insert_unique(59);
iht.insert_unique(63);
iht.insert_unique(108);
iht.insert_unique(2);
iht.insert_unique(53);
iht.insert_unique(55);
cout << iht.size() << endl; //6
//声明一个hashtable迭代器,将所有节点值打印出来
hashtable<int, int, hash<int>, identity<int>, equal_to<int>, alloc>
::iterator ite = iht.begin();
for(int i = 0; i < iht.size(); ++i, ++ite)
cout << *ite << ' '; // 53 55 2 108 59 63
cout << endl;
//遍历所有buckets,如果其节点个数不为0,就打印出节点个数
for(int i = 0; i < iht.bucket_count(); ++i)
{
int n = iht.elems_in_bucket(i);
if(n != 0)
cout << "bucket[ " << i << " ] has " << n << " elems." << endl;
}
//bucket[0] has 1 elems.
//bucket[2] has 3 elems.
//bucket[6] has 1 elems.
//bucket[10] has 1 elems.
}
C++11引入的容器unordered_set
、unordered_multiset
、unordered_map
和unordered_multimap
更名自gcc2.9的容器hash_set
、hash_multiset
、hash_map
和hash_multimap
,其底层封装了hashtable
.用法与set
、multiset
、map
和multimap
类似