容器hash_set是以hash table為底層機制的,幾乎所有的操作都是轉調用hash table提供的接口。由于插入無法存儲相同的鍵值,所以hash_set的插入操作全部都使用hash table的insert_unique接口,代碼如下:
~~~
pair<iterator, bool> insert(const value_type& obj)
{
pair<typename ht::iterator, bool> p = rep.insert_unique(obj);
return pair<iterator, bool>(p.first, p.second);
}
~~~
再看一下一個構造函數:
~~~
private:
typedef hashtable<Value, Value, HashFcn, identity<Value>,
EqualKey, Alloc> ht;
ht rep; // 底層機制——hash table
public:
hash_set() : rep(100, hasher(), key_equal()) {} // 默認大小為100
~~~
這里把hash table的表格大小,也就是vector大小設置為了100,那么在初始化hash table時,會自動選擇最接近的質數為197。也就是說一開始hash_set便擁有了197個“桶”。
下面來比較一下set和hash_set的異同:
set的底層機制為紅黑樹,hash_set的底層機制為hash table,兩者都能進行高效率的搜索。紅黑樹利用了二叉搜索樹的特性,而hash table則利用散列技術。但紅黑樹有自動排序功能而hash table沒有,反映出來的結果就是,set的元素有自動排序功能而hash_set沒有。下面是測試代碼:
~~~
#include <iostream>
#include <hash_set>
using namespace std;
using namespace __gnu_cxx;
int main()
{
hash_set<int> set;
set.insert(3);
set.insert(196);
set.insert(1);
set.insert(389);
set.insert(194);
set.insert(387);
hash_set<int>::iterator iter = set.begin();
for ( ; iter != set.end(); ++iter)
cout << *iter << ' ';
return 0;
}
~~~
運行結果:

由于有197個桶,所以元素1、194、387被散列到1號桶;3、196、389被散列到3號桶。但新元素是插入到每個桶指向的鏈表的前端,所以就有了這樣的輸出順序。
參考:
《STL源碼剖析》 P270.
- 前言
- 順序容器 — heap
- 關聯容器 — 紅黑樹
- 關聯容器 — set
- 關聯容器 — map
- 關聯容器 — hashtable
- 關聯容器 — hash_set
- 關聯容器 — hash_map
- 算法 — copy
- 順序容器 — stack
- 順序容器 — queue
- 順序容器 — priority_queue
- 順序容器 — slist
- construct()和destroy()
- 空間配置器
- 函數適配器
- 迭代器以及“特性萃取機”iterator_traits
- 算法 — partial_sort
- 算法 — sort
- 仿函數
- 適配器(adapters)
- C++簡易vector
- C++簡易list
- STL算法實現
- C++模板Queue