您的位置:首页 > 其它

hashtable

2016-03-23 10:00 288 查看
红黑树的插入、查找、删除的平均时间复杂度为O(nlogn)。当基于假设:输入数据具有随机性时,hashtable插入、查找、删除时间复杂度O(l)。

STL里的hash函数是采用开链法解决碰撞问题,bucket 聚合体是一个vector,便于动态维护,vector里每个元素指向一个bucket list。

如下:

template <class Value>
struct __hashtable_node {
__hashtable_node* next;
Value val;
};


hashtable的迭代器是单向的,所以没有后退操作,迭代器实现重要部分如下:

struct __hashtable_iterator
{
typedef hashtable<Value, Key, HashFcn, ExtractKey, EqualKey, Alloc>   hashtable;
typedef __hashtable_node<Value> node;
typedef forward_iterator_tag iterator_category;

node* cur;            // 当前的位置, 是线性表中的链表结点
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;              // 当前链表结点的下一个结点, 如果不为0
// 那么它就是我们要的

// 链表结点恰好是最后一个结点, 我们要在线性表的下一个表格的链表中查找
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;      // 触发operator ++()
return tmp;
}
}


STL中设计表格大小为质数,一般选择“最接近某数并大于某数”

static const int __stl_num_primes = 28;
static const unsigned long __stl_prime_list[__stl_num_primes] =
{
53,         97,           193,         389,       769,
1543,       3079,         6151,        12289,     24593,
49157,      98317,        196613,      393241,    786433,
1572869,    3145739,      6291469,     12582917,  25165843,
50331653,   100663319,    201326611,   402653189, 805306457,
1610612741, 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 + __stl_num_primes;
const unsigned long* pos = lower_bound(first, last, n);  //泛型算法
return pos == last ? *(last - 1) : *pos;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: