字串的雜湊函式:f(s) = 5*f(s+1) + *s
,當len(s)==1, 則f(s)=*s
;其中s是指向字串的指標。
sgi hash_table碰撞檢測方法是鏈結法,雜湊表的每個槽都包含乙個鍊錶(見《演算法導論》第11章 雜湊表)。// 示例
inline size_t __stl_hash_string(const
char* __s)
template
<> struct hash
};
// 雜湊表結點
template
struct _hashtable_node
; // 迭代器型別,前向迭代器
template
class _extractkey, class _equalkey, class _alloc>
struct _hashtable_iterator
// 迭代器++實現
template
_hashtable_iterator<_val,_key,_hf,_exk,_eqk,_all>&
_hashtable_iterator<_val,_key,_hf,_exk,_eqk,_all>::operator++()
return *this;
}// 雜湊表初始大小,全部為質數
enum ;
static
const
unsigned
long __stl_prime_list[__stl_num_primes] =
;template
class _extractkey, class _equalkey, class _alloc>
class hashtable
size_type _m_bkt_num(const value_type& __obj) const
size_type _m_bkt_num_key(const key_type& __key, size_t __n) const
size_type _m_bkt_num(const value_type& __obj, size_t __n) const
// 注意賦值操作先將原雜湊表清空,然後再賦值
hashtable& operator= (const hashtable& __ht)
return *this;
} void swap(hashtable& __ht)
...}// 注意:resize時候,只有當resize的大小大於原雜湊表的大小,才調整大小。而當resize的大小
// 小於原雜湊表時,不採取任何操作。
template
void hashtable<_val,_key,_hf,_ex,_eq,_all>::resize(size_type __num_elements_hint)
}_m_buckets.swap(__tmp);
}# ifdef __stl_use_exceptions
catch(...)
}throw;
}# endif /* __stl_use_exceptions */}}}
// 一下幾種插入方式
template
pair::iterator, bool>
hashtable<_val,_key,_hf,_ex,_eq,_all>::insert_unique_noresize(const value_type& __obj)
template
typename hashtable<_val,_key,_hf,_ex,_eq,_all>::iterator
hashtable<_val,_key,_hf,_ex,_eq,_all>::insert_equal_noresize(const value_type& __obj)
_node* __tmp = _m_new_node(__obj);
__tmp->_m_next = __first;
_m_buckets[__n] = __tmp;
++_m_num_elements;
return iterator(__tmp, this);
}// 只有兩個雜湊表中大小相等,且所有對應槽鍊錶中元素的都相等,這兩個雜湊表才相等
template
bool
operator==(const hashtable<_val,_key,_hf,_ex,_eq,_all>& __ht1,
const hashtable<_val,_key,_hf,_ex,_eq,_all>& __ht2)
if (__cur1 || __cur2)
return
false;
} return
true;
} // clear只是清除所有鍊錶中的結點,並不會清除槽_m_buckets,槽是乙個vector<_node*, _alloc>的成員變數
// 呼叫hashtable的析構函式時,會自動釋放槽的記憶體
template
void hashtable<_val,_key,_hf,_ex,_eq,_all>::clear()
_m_buckets[__i] = 0;
} _m_num_elements = 0;
}// erase只是擦除指定位置或指定鍵值的結點,並不會擦除槽
template
typename hashtable<_val,_key,_hf,_ex,_eq,_all>::size_type
hashtable<_val,_key,_hf,_ex,_eq,_all>::erase(const key_type& __key)
else
}if (_m_equals(_m_get_key(__first->_m_val), __key))
} return __erased;
}
// 無序關聯容器hash_map,由雜湊表實現,相當於hashtable的包裝類,對應於c++11中的unordered_map。
// hash_map中的鍵值是無序的,每乙個鍵值都是唯一的。
template class hash_map
// 對應於c++11中的unordered_multimap,鍵值可以重複
template class hash_multimap
sgi stl// 對應於c++11中的unordered_set,每乙個值都是唯一的
template class hash_set
// 對應於c++11中的unordered_multiset,可以有重複的值
template class hash_multiset
cppreference.com
STL 原始碼閱讀
1 這裡可以看出來,容器將迭代器作為類成員。vectora iteratorite a.begin 容器的成員函式可以返回迭代器,所以迭代器是容器的成員物件。2 個人理解,迭代器是對指標的封裝和提公升,盡可能遮蔽資料結構的底層細節,對外提供統一的操作介面,這些介面跟普通指標的功能類似,比如自增或自減...
STL原始碼閱讀 二
vector的記憶體分配基類 template class vector alloc base vector alloc base的偏特化版本,不需要儲存記憶體分配器 template class vector alloc base tp,allocator,true template struct...
STL原始碼閱讀 七
set使用紅黑樹實現,每個鍵值都不相同,且按序儲存。注意operator 即 rb tree的實現 先銷毀賦值號左邊的set,然後將右邊的set拷貝給左邊的set,而不是原值替換。set的所有函式都是用 rb tree的函式實現的,相當於 rb tree的乙個包裝類。multiset使用紅黑樹實現,...