📄 stl_hashtable.h
字号:
node* new_node(const value_type& obj) { node* n = node_allocator::allocate(); n->next = 0; __STL_TRY { construct(&n->val, obj); return n; } __STL_UNWIND(node_allocator::deallocate(n)); } void delete_node(node* n) { destroy(&n->val); node_allocator::deallocate(n); } void erase_bucket(const size_type n, node* first, node* last); void erase_bucket(const size_type n, node* last); void copy_from(const 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; 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; return tmp;}template <class V, class K, class HF, class ExK, class EqK, class A>__hashtable_const_iterator<V, K, HF, ExK, EqK, A>&__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(){ const node* old = cur; cur = cur->next; 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_const_iterator<V, K, HF, ExK, EqK, A>__hashtable_const_iterator<V, K, HF, ExK, EqK, A>::operator++(int){ const_iterator tmp = *this; ++*this; return tmp;}#ifndef __STL_CLASS_PARTIAL_SPECIALIZATIONtemplate <class V, class K, class HF, class ExK, class EqK, class All>inline forward_iterator_tagiterator_category(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&){ return forward_iterator_tag();}template <class V, class K, class HF, class ExK, class EqK, class All>inline V* value_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&){ return (V*) 0;}template <class V, class K, class HF, class ExK, class EqK, class All>inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*distance_type(const __hashtable_iterator<V, K, HF, ExK, EqK, All>&){ return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;}template <class V, class K, class HF, class ExK, class EqK, class All>inline forward_iterator_tagiterator_category(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&){ return forward_iterator_tag();}template <class V, class K, class HF, class ExK, class EqK, class All>inline V* value_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&){ return (V*) 0;}template <class V, class K, class HF, class ExK, class EqK, class All>inline hashtable<V, K, HF, ExK, EqK, All>::difference_type*distance_type(const __hashtable_const_iterator<V, K, HF, ExK, EqK, All>&){ return (hashtable<V, K, HF, ExK, EqK, All>::difference_type*) 0;}#endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */template <class V, class K, class HF, class Ex, class Eq, class A>bool operator==(const hashtable<V, K, HF, Ex, Eq, A>& ht1, const hashtable<V, K, HF, Ex, Eq, A>& ht2){ typedef typename hashtable<V, K, HF, Ex, Eq, A>::node node; if (ht1.buckets.size() != ht2.buckets.size()) return false; for (int n = 0; n < ht1.buckets.size(); ++n) { node* cur1 = ht1.buckets[n]; node* cur2 = ht2.buckets[n]; for ( ; cur1 && cur2 && cur1->val == cur2->val; cur1 = cur1->next, cur2 = cur2->next) {} if (cur1 || cur2) return false; } return true;} #ifdef __STL_FUNCTION_TMPL_PARTIAL_ORDERtemplate <class Val, class Key, class HF, class Extract, class EqKey, class A>inline void swap(hashtable<Val, Key, HF, Extract, EqKey, A>& ht1, hashtable<Val, Key, HF, Extract, EqKey, A>& ht2) { ht1.swap(ht2);}#endif /* __STL_FUNCTION_TMPL_PARTIAL_ORDER */template <class V, class K, class HF, class Ex, class Eq, class A>pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, bool> hashtable<V, K, HF, Ex, Eq, A>::insert_unique_noresize(const value_type& obj){ const size_type n = bkt_num(obj); node* first = buckets[n]; for (node* cur = first; cur; cur = cur->next) if (equals(get_key(cur->val), get_key(obj))) return pair<iterator, bool>(iterator(cur, this), false); node* tmp = new_node(obj); tmp->next = first; buckets[n] = tmp; ++num_elements; return pair<iterator, bool>(iterator(tmp, this), true);}template <class V, class K, class HF, class Ex, class Eq, class A>typename hashtable<V, K, HF, Ex, Eq, A>::iterator hashtable<V, K, HF, Ex, Eq, A>::insert_equal_noresize(const value_type& obj){ const size_type n = bkt_num(obj); node* first = buckets[n]; for (node* cur = first; cur; cur = cur->next) if (equals(get_key(cur->val), get_key(obj))) { node* tmp = new_node(obj); tmp->next = cur->next; cur->next = tmp; ++num_elements; return iterator(tmp, this); } node* tmp = new_node(obj); tmp->next = first; buckets[n] = tmp; ++num_elements; return iterator(tmp, this);}template <class V, class K, class HF, class Ex, class Eq, class A>typename hashtable<V, K, HF, Ex, Eq, A>::reference hashtable<V, K, HF, Ex, Eq, A>::find_or_insert(const value_type& obj){ resize(num_elements + 1); size_type n = bkt_num(obj); node* first = buckets[n]; for (node* cur = first; cur; cur = cur->next) if (equals(get_key(cur->val), get_key(obj))) return cur->val; node* tmp = new_node(obj); tmp->next = first; buckets[n] = tmp; ++num_elements; return tmp->val;}template <class V, class K, class HF, class Ex, class Eq, class A>pair<typename hashtable<V, K, HF, Ex, Eq, A>::iterator, typename hashtable<V, K, HF, Ex, Eq, A>::iterator> hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key){ typedef pair<iterator, iterator> pii; const size_type n = bkt_num_key(key); for (node* first = buckets[n]; first; first = first->next) { if (equals(get_key(first->val), key)) { for (node* cur = first->next; cur; cur = cur->next) if (!equals(get_key(cur->val), key)) return pii(iterator(first, this), iterator(cur, this)); for (size_type m = n + 1; m < buckets.size(); ++m) if (buckets[m]) return pii(iterator(first, this), iterator(buckets[m], this)); return pii(iterator(first, this), end()); } } return pii(end(), end());}template <class V, class K, class HF, class Ex, class Eq, class A>pair<typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator, typename hashtable<V, K, HF, Ex, Eq, A>::const_iterator> hashtable<V, K, HF, Ex, Eq, A>::equal_range(const key_type& key) const{ typedef pair<const_iterator, const_iterator> pii; const size_type n = bkt_num_key(key); for (const node* first = buckets[n] ; first; first = first->next) { if (equals(get_key(first->val), key)) { for (const node* cur = first->next; cur; cur = cur->next) if (!equals(get_key(cur->val), key)) return pii(const_iterator(first, this), const_iterator(cur, this)); for (size_type m = n + 1; m < buckets.size(); ++m) if (buckets[m]) return pii(const_iterator(first, this), const_iterator(buckets[m], this)); return pii(const_iterator(first, this), end()); } } return pii(end(), end());}template <class V, class K, class HF, class Ex, class Eq, class A>typename hashtable<V, K, HF, Ex, Eq, A>::size_type hashtable<V, K, HF, Ex, Eq, A>::erase(const key_type& key){ const size_type n = bkt_num_key(key); node* first = buckets[n]; size_type erased = 0; if (first) { node* cur = first; node* next = cur->next; while (next) { if (equals(get_key(next->val), key)) { cur->next = next->next; delete_node(next); next = cur->next; ++erased; --num_elements; } else { cur = next; next = cur->next; } } if (equals(get_key(first->val), key)) { buckets[n] = first->next; delete_node(first); ++erased; --num_elements; } } return erased;}template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::erase(const iterator& it){ if (node* const p = it.cur) { const size_type n = bkt_num(p->val); node* cur = buckets[n]; if (cur == p) { buckets[n] = cur->next; delete_node(cur); --num_elements; } else { node* next = cur->next; while (next) { if (next == p) { cur->next = next->next; delete_node(next); --num_elements; break; } else { cur = next; next = cur->next; } } } }}template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::erase(iterator first, iterator last){ size_type f_bucket = first.cur ? bkt_num(first.cur->val) : buckets.size(); size_type l_bucket = last.cur ? bkt_num(last.cur->val) : buckets.size(); if (first.cur == last.cur) return; else if (f_bucket == l_bucket) erase_bucket(f_bucket, first.cur, last.cur); else { erase_bucket(f_bucket, first.cur, 0); for (size_type n = f_bucket + 1; n < l_bucket; ++n) erase_bucket(n, 0); if (l_bucket != buckets.size()) erase_bucket(l_bucket, last.cur); }}template <class V, class K, class HF, class Ex, class Eq, class A>inline voidhashtable<V, K, HF, Ex, Eq, A>::erase(const_iterator first, const_iterator last){ erase(iterator(const_cast<node*>(first.cur), const_cast<hashtable*>(first.ht)), iterator(const_cast<node*>(last.cur), const_cast<hashtable*>(last.ht)));}template <class V, class K, class HF, class Ex, class Eq, class A>inline voidhashtable<V, K, HF, Ex, Eq, A>::erase(const const_iterator& it){ erase(iterator(const_cast<node*>(it.cur), const_cast<hashtable*>(it.ht)));}template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::resize(size_type num_elements_hint){ const size_type old_n = buckets.size(); if (num_elements_hint > old_n) { const size_type n = next_size(num_elements_hint); if (n > old_n) { vector<node*, A> tmp(n, (node*) 0); __STL_TRY { for (size_type bucket = 0; bucket < old_n; ++bucket) { node* first = buckets[bucket]; while (first) { size_type new_bucket = bkt_num(first->val, n); buckets[bucket] = first->next; first->next = tmp[new_bucket]; tmp[new_bucket] = first; first = buckets[bucket]; } } buckets.swap(tmp); }# ifdef __STL_USE_EXCEPTIONS catch(...) { for (size_type bucket = 0; bucket < tmp.size(); ++bucket) { while (tmp[bucket]) { node* next = tmp[bucket]->next; delete_node(tmp[bucket]); tmp[bucket] = next; } } throw; }# endif /* __STL_USE_EXCEPTIONS */ } }}template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* first, node* last){ node* cur = buckets[n]; if (cur == first) erase_bucket(n, last); else { node* next; for (next = cur->next; next != first; cur = next, next = cur->next) ; while (next) { cur->next = next->next; delete_node(next); next = cur->next; --num_elements; } }}template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::erase_bucket(const size_type n, node* last){ node* cur = buckets[n]; while (cur != last) { node* next = cur->next; delete_node(cur); cur = next; buckets[n] = cur; --num_elements; }}template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::clear(){ for (size_type i = 0; i < buckets.size(); ++i) { node* cur = buckets[i]; while (cur != 0) { node* next = cur->next; delete_node(cur); cur = next; } buckets[i] = 0; } num_elements = 0;} template <class V, class K, class HF, class Ex, class Eq, class A>void hashtable<V, K, HF, Ex, Eq, A>::copy_from(const hashtable& ht){ buckets.clear(); buckets.reserve(ht.buckets.size()); buckets.insert(buckets.end(), ht.buckets.size(), (node*) 0); __STL_TRY { for (size_type i = 0; i < ht.buckets.size(); ++i) { if (const node* cur = ht.buckets[i]) { node* copy = new_node(cur->val); buckets[i] = copy; for (node* next = cur->next; next; cur = next, next = cur->next) { copy->next = new_node(next->val); copy = copy->next; } } } num_elements = ht.num_elements; } __STL_UNWIND(clear());}__STL_END_NAMESPACE#endif /* __SGI_STL_INTERNAL_HASHTABLE_H */// Local Variables:// mode:C++// End:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -