设为首页 - 加入收藏 ASP站长网(Aspzz.Cn)- 科技、建站、经验、云计算、5G、大数据,站长网!
热搜: 手机 数据 公司
当前位置: 首页 > 服务器 > 安全 > 正文

【数据结构】散列表(2)

发布时间:2021-03-30 15:03 所属栏目:53 来源:网络整理
导读://对于字符串类型char*的函数的转换函数inline size_t __stl_hash_string(const char* s){ unsigned long h = 0; for ( ; *s; ++s) h = 5*h + *s; return size_t(h);}__STL_TEMPLATE_NULL struct hashchar*{ size_t

//对于字符串类型char*的函数的转换函数
inline size_t __stl_hash_string(const char* s)
{
  unsigned long h = 0; 
  for ( ; *s; ++s)
    h = 5*h + *s;
  
  return size_t(h);
}

__STL_TEMPLATE_NULL struct hash<char*>
{
  size_t operator()(const char* s) const { return __stl_hash_string(s); }
};

__STL_TEMPLATE_NULL struct hash<const char*>
{
  size_t operator()(const char* s) const { return __stl_hash_string(s); }
};

__STL_TEMPLATE_NULL struct hash<char> {
  size_t operator()(char x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<unsigned char> {
  size_t operator()(unsigned char x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<signed char> {
  size_t operator()(unsigned char x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<short> {
  size_t operator()(short x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<unsigned short> {
  size_t operator()(unsigned short x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<int> {
  size_t operator()(int x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<unsigned int> {
  size_t operator()(unsigned int x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<long> {
  size_t operator()(long x) const { return x; }
};
__STL_TEMPLATE_NULL struct hash<unsigned long> {
  size_t operator()(unsigned long x) const { return x; }
};

散列表插入元素(元素值不允许重复)

  //插入元素,元素值不允许重复
  pair<iterator,bool> insert_unique(const value_type& obj)
  {
    resize(num_elements + 1);   //判断是否需要重建表格
    return insert_unique_noresize(obj);   //插入元素,键值不允许重复
  }

//判断是否需要重建表格
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();		//buckets中的表格大小
  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);       //创建新的bucket
      __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);		//计算新的插入位置,因为n改变了
            buckets[bucket] = first->next;			//旧的散列表先指向下一个元素
            first->next = tmp[new_bucket];			//first指向新的散列表中元素指针
            tmp[new_bucket] = first;				    //新的散列表指向first
            first = buckets[bucket];				    //再次指向旧的散列表的指针
          }
        }
        buckets.swap(tmp);      //交换
      }
  }
}

//在不需要重建表格的情况下,元素值是不允许重复的
template <class V,class A>
pair<typename hashtable<V,A>::iterator,bool> 
hashtable<V,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;				//表中指针指向tmp
  ++num_elements;			  	//更新节点的个数
  return pair<iterator,bool>(iterator(tmp,true);
}


散列表插入元素(元素值允许重复)

  iterator insert_equal(const value_type& obj)
  {
    resize(num_elements + 1);   //是否重建表格
    return insert_equal_noresize(obj);  //插入元素,元素值可以重复
  }


//允许元素值重复
template <class V,class A>
typename hashtable<V,A>::iterator 
hashtable<V,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);
}

查找元素

  //找到某个键值
  iterator find(const key_type& key) 
  {
    size_type n = bkt_num_key(key);   //找到插入位置
    node* first;
    for ( first = buckets[n];         //从首指针开始查找判断
          first && !equals(get_key(first->val),key);	//判断键值相同的
          first = first->next)
      {}
    return iterator(first,this);
  } 

(编辑:ASP站长网)

网友评论
推荐文章
    热点阅读