算法导论十一章

    技术2022-05-11  53

    散列表: 本章介绍了散列表的各种问题。

    散列函数:除法散列,乘法散列,全域散列。 其中除法散列是简单的mod.  乘法散列为h(k) = m(kA mod 1). 即关键字k乘常数A, 然后取小数部分, 乘以m. 全域散列是一组散列函数,这些函数都可以将关键字域U映射到相同的集合中, 同时对k, l 属于U. 满足h(k) = h(l)的散列函数的个数最多是: 散列函数的数目/集合的大小. 散列表的2种解决冲突的办法: 链接法和开放寻址法。链接法比较简单, 开发寻址法解决冲突的探查函数有几种: 线形探察, 二次探察, 双重散列。 其中双重探察的探察序列最多,所以相应散列效果更好。最后介绍了完全散列, 这节难度较大, 没有看太明白, 主要是对于全域散列的证明很头疼阿。我自己的链接法的实现: 因为很少用到散列, 所以只是做了少量的测试。 而且散列函数的返回值一定是int_type. 对于散列的应用了解少了点,所以模板参数的定义可能不是很合理。template <class Key, class Value, class Hash = HashDivide<Key> >class LinkHash{public: typedef Key key_type; typedef Value data_type; typedef std::pair<Key, Value> value_type; typedef value_type& value_reference; typedef const value_type& value_const_reference; typedef key_type& key_reference; typedef const key_type& key_const_reference; typedef value_type* value_pointer; typedef const value_type* value_const_pointer;

     typedef LinkNode<value_type>* node_type;

     LinkHash(int size) {  m_container.assign(size, 0);  m_size = 0; }  ~LinkHash() {  for (std::vector< node_type >::iterator it = m_container.begin(); it != m_container.end(); ++it)  {   node_type node = *it;   while (node)   {    *it = node->next();    delete node;    node = *it;   }  } }

     size_t size() const {return m_size;}

     data_type get(const key_type& key) {  node_type node = find(key);  if (node)  {   return node->value().second;  }  else  {   throw std::out_of_range("no key");  } }

     bool insert(const key_type& key, const data_type& value) {  return insert(value_type(key, value)); } bool insert(value_const_reference data) {  node_type node = find(data.first);  if (node)  {   node->value().second = data.second;   return false;  }  else  {   node_type node = new LinkNode<value_type>();   node->m_data = data;   node->m_next = m_container[hash(data.first)];   m_container[hash(data.first)] = node;   ++m_size;   return true;  } }

     bool has_key(const key_type& key) {  node_type node = find(key);  if (node)   return true;  else   return false; }

     bool erase(const key_type& key) {  assert(hash(key));  int index = hash(key);  if (index >= m_container.size())  {   throw bucketNotEnough("bucket not enough");  }  LinkNode<value_type> nodeImp;  node_type node = &nodeImp;  node->m_next = m_container[index];  while(node->next())  {   if (node->next()->value().first == key)   {    node_type eraseNode = node->next();    node->m_next = node->next()->next();    delete eraseNode;    --m_size;    m_container[index] = node->m_next;    return true;   }   node = node->next();  }  return false; }

    private:

     node_type find(const key_type& key) {  int index = hash(key);  if (index >= m_container.size())  {   throw bucketNotEnough("bucket not enough");  }  node_type node = m_container[index];  while(node)  {   if (node->value().first == key)   {    return node;   }   node = node->next();  }  return 0; }

     int hash(const key_type& key) {  return m_function(key) % m_container.size(); }

    private: LinkHash(const LinkHash&); LinkHash& operator=(const LinkHash&); std::vector< node_type > m_container; Hash m_function; size_t m_size;}; 


    最新回复(0)