紅黑樹的插入、查找、刪除的平均時間複雜度爲O(nlogn)。當基於假設:輸入數據具備隨機性時,hashtable插入、查找、刪除時間複雜度O(l)。node
STL裏的hash函數是採用開鏈法解決碰撞問題,bucket 聚合體是一個vector,便於動態維護,vector裏每一個元素指向一個bucket list。算法
以下:函數
template <class Value> struct __hashtable_node { __hashtable_node* next; Value val; };
hashtable的迭代器是單向的,因此沒有後退操做,迭代器實現重要部分以下:this
struct __hashtable_iterator { typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc> hashtable; typedef __hashtable_node<Value> node; typedef forward_iterator_tag iterator_category; node* cur; // 當前的位置, 是線性表中的鏈表結點 hashtable* ht; // 線性表中的位置 template <class V, class K, class HF, class ExK, class EqK, class A> __hashtable_iterator<V, K, HF, ExK, EqK, A>& __hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++() { const node* old = cur; cur = cur->next; // 當前鏈表結點的下一個結點, 若是不爲0 // 那麼它就是咱們要的 // 鏈表結點剛好是最後一個結點, 咱們要在線性表的下一個表格的鏈表中查找 if (!cur) { size_type bucket = ht->bkt_num(old->val); while (!cur && ++bucket < ht->buckets.size()) cur = ht->buckets[bucket]; } return *this; } template <class V, class K, class HF, class ExK, class EqK, class A> inline __hashtable_iterator<V, K, HF, ExK, EqK, A> __hashtable_iterator<V, K, HF, ExK, EqK, A>::operator++(int) { iterator tmp = *this; ++*this; // 觸發operator ++() return tmp; } }
STL中設計表格大小爲質數,通常選擇「最接近某數並大於某數」spa
static const int __stl_num_primes = 28; 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 }; // 返回大於n的最小素數 inline unsigned long __stl_next_prime(unsigned long n) { const unsigned long* first = __stl_prime_list; const unsigned long* last = __stl_prime_list + __stl_num_primes; const unsigned long* pos = lower_bound(first, last, n); //泛型算法 return pos == last ? *(last - 1) : *pos; }