STL關聯容器值hashtable

2022-07-17 18:57:14 字數 3313 閱讀 2702

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 無...