赞
踩
前面介绍的关联容器set、multiset、map和multimap的底层机制都是基于RB-Tree红黑树,虽然能够实现在插入、删除和搜素操作能够达到对数平均时间,可是要求输入数据有足够的随机性。本文介绍的hash table不需要要求输入数据具有随机性,在插入、删除和搜素操作都能达到常数平均时间。本文介绍的hash table是来自SGI STL中的<stl_hashtable.h>文件,在这里为了避免冲突(即不同元素映射到相同的键值位置),采用了拉链法来解决冲突问题。SGI中实现hash table的方式,在每个表格元素中维护一个链表, 然后在链表上执行元素的插入、搜寻、删除等操作,该表格中的每个元素被称为桶(bucket)。有关hash table的介绍可往前面博文《散列表》查看。
- #ifndef __SGI_STL_INTERNAL_HASHTABLE_H
- #define __SGI_STL_INTERNAL_HASHTABLE_H
-
- // Hashtable class, used to implement the hashed associative containers
- // hash_set, hash_map, hash_multiset, and hash_multimap.
-
- //SGI STL的hashtable的实现方法是拉链法.
- //拉链法可以避免hashtable的冲突问题,即不同数据映射到同一的hash值
-
- //有关hashtable的介绍见前文:
- //http://blog.csdn.net/chenhanzhun/article/details/38091431
-
- #include <stl_algobase.h>
- #include <stl_alloc.h>
- #include <stl_construct.h>
- #include <stl_tempbuf.h>
- #include <stl_algo.h>
- #include <stl_uninitialized.h>
- #include <stl_function.h>
- #include <stl_vector.h>
- #include <stl_hash_fun.h>
-
- __STL_BEGIN_NAMESPACE
-
- //hashtable中链表的节点结构
- //类似于单链表的节点结构
- template <class _Val>
- struct _Hashtable_node
- {
- _Hashtable_node* _M_next;//指向下一节点
- _Val _M_val;//节点元素值
- };
-
- //这里使用前置声明, 避免在后面交叉引用会导致编译错误
- template <class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc = alloc>
- class hashtable;
-
- template <class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_iterator;
-
- template <class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_const_iterator;
-
- //hashtable迭代器定义
- //注意:hash table迭代器没有提供后退操作operator--
- //也没用提供逆向迭代器reverse iterator
- template <class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_iterator {
- //内嵌类型别名
- typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
- _Hashtable;
- typedef _Hashtable_iterator<_Val, _Key, _HashFcn,
- _ExtractKey, _EqualKey, _Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
- _ExtractKey, _EqualKey, _Alloc>
- const_iterator;
- typedef _Hashtable_node<_Val> _Node;
-
- typedef forward_iterator_tag iterator_category;//采用正向迭代器
- typedef _Val value_type;
- typedef ptrdiff_t difference_type;
- typedef size_t size_type;
- typedef _Val& reference;
- typedef _Val* pointer;
-
- _Node* _M_cur;//当前迭代器所指位置
- _Hashtable* _M_ht;//hashtable中的位置,控制访问桶子连续性
-
- _Hashtable_iterator(_Node* __n, _Hashtable* __tab)
- : _M_cur(__n), _M_ht(__tab) {}
- _Hashtable_iterator() {}
- //返回当前节点元素值的引用
- reference operator*() const { return _M_cur->_M_val; }
- #ifndef __SGI_STL_NO_ARROW_OPERATOR
- pointer operator->() const { return &(operator*()); }
- #endif /* __SGI_STL_NO_ARROW_OPERATOR */
- //操作符重载定义在后面定义
- iterator& operator++();
- iterator operator++(int);
- //比较两个迭代器是否指向同一个节点
- bool operator==(const iterator& __it) const
- { return _M_cur == __it._M_cur; }
- bool operator!=(const iterator& __it) const
- { return _M_cur != __it._M_cur; }
- };
-
-
- //下面是const iterator的定义,基本和上面相同
- template <class _Val, class _Key, class _HashFcn,
- class _ExtractKey, class _EqualKey, class _Alloc>
- struct _Hashtable_const_iterator {
- typedef hashtable<_Val,_Key,_HashFcn,_ExtractKey,_EqualKey,_Alloc>
- _Hashtable;
- typedef _Hashtable_iterator<_Val,_Key,_HashFcn,
- _ExtractKey,_EqualKey,_Alloc>
- iterator;
- typedef _Hashtable_const_iterator<_Val, _Key, _HashFcn,
- _ExtractKey, _EqualKey, _Alloc>
- const_iterator;
- typedef _Hashtable_node<_Val> _Node;
-
- typedef forward_iterator_tag iterator_category;
- typedef _Val value_type;
- typedef ptrdiff_t difference_type;
- typedef size_t size_type;
- typedef const _Val& reference;
- typedef const _Val* pointer;
-
- const _Node* _M_cur;
- const _Hashtable* _M_ht;
-
- _Hashtable_const_iterator(const _Node* __n, const _Hashtable* __tab)
- : _M_cur(__n), _M_ht(__tab) {}
- _Hashtable_const_iterator() {}
- _Hashtable_const_iterator(const iterator& __it)
- : _M_cur(__it._M_cur), _M_ht(__it._M_ht) {}
- reference operator*() const { return _M_cur->_M_val; }
- #ifndef __SGI_STL_NO_ARROW_OPERATOR
- pointer operator->() const { return &(operator*()); }
- #endif /* __SGI_STL_NO_ARROW_OPERATOR */
- const_iterator& operator++();
- const_iterator operator++(int);
- bool operator==(const const_iterator& __it) const
- { return _M_cur == __it._M_cur; }
- bool operator!=(const const_iterator& __it) const
- { return _M_cur != __it._M_cur; }
- };
-
- // Note: assumes long is at least 32 bits.
- // 注意:假设long至少为32-bits, 可以根据自己需要修改
- //定义28个素数用作hashtable的大小
- enum { __stl_num_primes = 28 };
-
- static const unsigned long __stl_prime_list[__stl_num_primes] =
- {
- 53ul, 97ul, 193ul, 389ul, 769ul,
- 1543ul, 3079ul, 6151ul, 12289ul, 24593ul,
- 49157ul, 98317ul, 196613ul, 393241ul, 786433ul,
- 1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,
- 50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,
- 1610612741ul, 3221225473ul, 4294967291ul
- };
-
- //返回大于n的最小素数
- inline unsigned long __stl_next_prime(unsigned long __n)
- {
- const unsigned long* __first = __stl_prime_list;
- const unsigned long* __last = __stl_prime_list + (int)__stl_num_primes;
- const unsigned long* pos = lower_bound(__first, __last, __n);
- /*
- 上面的lower_bound调用的是STL中的算法lower_bound();
- 该算法的功能:
- Returns an iterator pointing to the first element in the range [first,last) which does not compare less than val.
- The elements in the range shall already be sorted according to this same criterion (operator< or comp)
- 即返回在[first,last)范围内第一个不小于val的位置
- 注意:调用该算法之前,[first,last)范围里面的元素必须已排序
- 该算法的原型如下:
- 第一个版本:采用默认比较准则operator<
- template <class ForwardIterator, class T>
- ForwardIterator lower_bound (ForwardIterator first, ForwardIterator last,
- const T& val);
- 第二版本:采用用户指定的比较函数comp
- te
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。