源代码来自sgi-2.91版本stl_hash_set.h
unordered_set总述
先了解hash表
(1)底层实现完全由hash表代替,最开始叫做hash_set,从实现原理来说unordered_set应该被称为容器适配器
(2)对底层hash表来说,键值就是实值
(3)hash表没有自动排序,所以相对于set,unordered_set没有自动排序
(4)unordered_set适合用于只查找元素的情况
unordered_set类
#ifndef __STL_LIMITED_DEFAULT_TEMPLATES
template <class Value, class HashFcn = hash<Value>, //hash函数来对元素编号
class EqualKey = equal_to<Value>, //比较==函数
class Alloc = alloc> //allco分配器
#else
template <class Value, class HashFcn, class EqualKey, class Alloc = alloc> //自定义参数
#endif
class hash_set
{
private:
typedef hashtable<Value, Value, HashFcn, identity<Value>,
EqualKey, Alloc> ht; //申明hash表
ht rep; //创建hash表
public:
typedef typename ht::key_type key_type;
typedef typename ht::value_type value_type;
typedef typename ht::hasher hasher;
typedef typename ht::key_equal key_equal;
typedef typename ht::size_type size_type;
typedef typename ht::difference_type difference_type;
typedef typename ht::const_pointer pointer;
typedef typename ht::const_pointer const_pointer;
typedef typename ht::const_reference reference;
typedef typename ht::const_reference const_reference;
typedef typename ht::const_iterator iterator; //注意此处,默认const_iterator
typedef typename ht::const_iterator const_iterator;
hasher hash_funct() const { return rep.hash_funct(); }
key_equal key_eq() const { return rep.key_eq(); }
hash_set默认构造
hash_set() : rep(100, hasher(), key_equal()) {} //默认构造,hash表中找到比100大的质数193作为buckets容量
explicit hash_set(size_type n) : rep(n, hasher(), key_equal()) {}
hash_set(size_type n, const hasher& hf) : rep(n, hf, key_equal()) {}
hash_set(size_type n, const hasher& hf, const key_equal& eql)
: rep(n, hf, eql) {}
size()
size_type size() const { return rep.size(); }
调用hash表的size
size_type size() const { return num_elements; } //返回元素个数,num_elements会随着插入删除变化
begin()、end()
iterator begin() const { return rep.begin(); }
iterator end() const { return rep.end(); }
find()
iterator find(const key_type& key) const { return rep.find(key); } //调用hash表find函数
在hash表中找元素,根据键值查找
iterator find(const key_type& key)
{
size_type n = bkt_num_key(key); //找到在buckets中落脚点
node* first;
for ( first = buckets[n];
first && !equals(get_key(first->val), key); //键值相等或first指向null时返回
first = first->next)
{}
return iterator(first, this); //返回一个迭代器
}
count()
统计有多少元素
size_type count(const key_type& key) const { return rep.count(key); }
insert()
pair<iterator, bool> insert(const value_type& obj)
{
pair<typename ht::iterator, bool> p = rep.insert_unique(obj); //在hash表的插入中会判断有没有重复元素
return pair<iterator, bool>(p.first, p.second); //first是迭代器,second代表是否成功插入
}
erase()
删除元素
size_type erase(const key_type& key) {return rep.erase(key); }
void erase(iterator it) { rep.erase(it); }
测试函数
#include<ostream>
#include<unordered_set>
using namespace std;
int main()
{
unordered_set<int> se;
unordered_set<int>::iterator it;
int val = 100;
for (int i = 0; i < val; i++)
se.insert(i);
//se.insert(10);
cout << *se.begin() << endl;
for (unsigned i = 0; i < se.bucket_count(); ++i) {
std::cout << "bucket #" << i << " contains:";
for (auto local_it = se.begin(i); local_it != se.end(i); ++local_it)
std::cout << " " << *local_it;
std::cout << std::endl;
}
}