hashtable(雜湊表)是一種資料結構,在元素的插入,刪除,搜尋操作上具有常數平均時間複雜度o(1);
雜湊函式:負責將某一元素對映為索引。
碰撞(collision):不同的元素被對映到相同的位置。
解決碰撞的方法:線性試探法,二次試探法,開鏈等。
負載係數:元素個數除以**大小。
主集團:平均插入成本的增長幅度,遠高於負載係數的成長幅度。
次集團:hashtable若採用二次探測,則若兩個元素經hash function計算出來的位置相同,則插入時所試探的位置也相同,造成某種浪費。
開鏈:在每個**元素中位置乙個list。
桶(bucket):hashtable**內的每個元素。
節點類
template struct _hashtable_node
;
hashtable的節點和list節點相類似。
乙個node的指標指向每個桶上列表的首個元素,而桶上的鍊錶首位址存放在vector向量中。
typedef _hashtable_node<_val> _node;
vector<_node*,_alloc> _m_buckets;
hashtable迭代器的自增操作符定義如下:
template _hashtable_iterator<_val,_key,_hf,_exk,_eqk,_all>&
_hashtable_iterator<_val,_key,_hf,_exk,_eqk,_all>::operator++()
return *this;
}
hashtable類定義有五個模板引數
template class hashtable;
_val 值型別
_key 鍵型別
_hashfcn 雜湊函式
_extractkey 提取鍵的方法
_equalkey 判斷鍵相等的方法
_alloc 分配器型別
insert_unique不允許值重複的插入:
pairinsert_unique(const value_type& __obj)
該函式首先呼叫resize函式,傳入當前元素加一的值,看是否需要進行擴容。處理完成後,再將值__obj插入到hashtable中。
resize函式的定義如下:
template void hashtable<_val,_key,_hf,_ex,_eq,_all>
::resize(size_type __num_elements_hint)
}//當舊hashtable中的元素都重新hash到新桶向量後
_m_buckets.swap(__tmp); //將新桶向量與舊桶向量相互交換。
//舊桶資料存放在__tmp向量中,當離開此範圍時,__tmp作為乙個區域性變數,其空間會被自動釋放。
}//發生異常後進行的回滾操作
# ifdef __stl_use_exceptions
catch(...)
}throw;
}# endif /* __stl_use_exceptions */
}}}
insert_unique_noresize的函式定義如下:
template pair::iterator, bool>
hashtable<_val,_key,_hf,_ex,_eq,_all>
::insert_unique_noresize(const value_type& __obj)
結合insert_unique函式中呼叫的兩個函式介面的分析,可知:
insert_equal允許重複的插入:
iterator insert_equal(const value_type& __obj)
與insert_unique相比較,函式在擴容後呼叫允許重複值的非擴充插入函式insert_equal_noresize:
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); //完成插入操作,返回
}
insert_unique_noresize與insert_equal_noresize的比較:
hashtable的刪除和複製
hashtable刪除
template void hashtable<_val,_key,_hf,_ex,_eq,_all>::clear()
_m_buckets[__i] = 0; //鍊錶開頭指向空
} _m_num_elements = 0; //更新元素數量為0
}
hashtable複製
template void hashtable<_val,_key,_hf,_ex,_eq,_all>
::_m_copy_from(const hashtable& __ht)}}
_m_num_elements = __ht._m_num_elements; //更新元素數量
} __stl_unwind(clear()); //複製發生異常時回滾操作
}
STL 關聯容器
1 關聯容器與順序容器的本質區別 關聯容器通過鍵 key 儲存和讀取元素,而順序容器則通過元素在容器中的位置順序儲存和訪問元素。2 關聯容器的型別 map set multimap multiset 3 pair型別 pair型別的比較 p1 p1 p2 如果兩個pair物件的first和secon...
stl 關聯容器
簡介 對於關聯容器,它的每個元素都有乙個鍵 key 容器中的元素的順序並不能人為隨意決定,而是按照鍵的取值公升序排列的。也就是說,對於乙個關聯容器s,使用迭代器在 s.begin s.end 區間內遍歷,訪問到的序列總是公升序的。分類 按照容器中是否允許出現重複鍵值,關聯容器可分為單重關聯容器和多重...
STL 關聯容器
c primer 第11章 關聯容器和順序容器有根本的不同 關聯容器中的元素是按關鍵字來儲存和訪問的。關聯容器型別 分為有序和無序 有序 map 關聯陣列 儲存鍵值對 set 關鍵字即值,即只儲存關鍵字的容器 multimap 關鍵字可重複出現的map multiset 關鍵字可重複出現的set 無...