STL原始碼閱讀 八

2021-07-16 06:24:27 字數 3455 閱讀 3127

字串的雜湊函式:f(s) = 5*f(s+1) + *s,當len(s)==1, 則f(s)=*s;其中s是指向字串的指標。

// 示例

inline size_t __stl_hash_string(const

char* __s)

template

<> struct hash

};

sgi hash_table碰撞檢測方法是鏈結法,雜湊表的每個槽都包含乙個鍊錶(見《演算法導論》第11章 雜湊表)。

// 雜湊表結點

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

// 對應於c++11中的unordered_set,每乙個值都是唯一的

template class hash_set

// 對應於c++11中的unordered_multiset,可以有重複的值

template class hash_multiset

sgi stl

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使用紅黑樹實現,...