散列表(哈希表)是普通数组概念的推广。在散列表中,不是直接把关键字作为数组的下标,而是根据关键字计算出相应的下标。
一个散列表中重要的是他的散列函数以及解决冲突的方法。
这里试着自己模仿网上STL中hash表的实现写了一个,记在这里以便以后查看。
这里散列函数选择的是除法散列法,解决冲突的方法选用的是链接法,表基于vector实现。
代码如下:
//hashtable.h
#ifndef HASHTABLE_H
#define HASHTABLE_H
#include<iostream>
#include<algorithm>
#include<vector>
#include<string.h>
#include<memory>
template<class ValueType>
struct __hashtable_node
{
__hashtable_node *next;
ValueType val;
};
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,
16106122741,3221225473ul,4294967291ul
};
inline unsigned long __get_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=std::lower_bound(first,last,n);
return pos==last?*(last-1):*pos;
}
template<class T1,class T2>
void construct(T1 *p,const T2 &value)
{
new (p) T1(value);
}
template<class T>
void destroy(T *pointer)
{
pointer->~T();
}
//hash函数定义(仿函数)
template<class KeyType>
struct hash
{
};
inline size_t __stl_hash_string(const char *s)
{
unsigned long h=0;
while(*s)
{
h=5*h+*s;
}
return size_t(h);
}
template<>
struct hash<int>
{
size_t operator()(int x) const {return x;}
};
template<>
struct hash<unsigned int>
{
size_t operator()(unsigned int x) const {return x;}
};
template<>
struct hash<short>
{
size_t operator()(short x) const {return x;}
};
template<>
struct hash<unsigned short>
{
size_t operator()(unsigned short x) const {return x;}
};
template<>
struct hash<long>
{
size_t operator()(long x) const {return x;}
};
template<>
struct hash<unsigned long>
{
size_t operator()(unsigned long x) const {return x;}
};
template<>
struct hash<char *>
{
size_t operator()(const char *s) const
{
return __stl_hash_string(s);
}
};
template<>
struct hash<const char *>
{
size_t operator()(const char *s) const
{
return __stl_hash_string(s);
}
};
template<>
struct hash<char>
{
size_t operator()(char s) const{return s;}
};
template<>
struct hash<unsigned char>
{
size_t operator()(unsigned char s) const{return s;}
};
template<>
struct hash<signed char>
{
size_t operator()(signed char s) const{return s;}
};
template<class Arg,class Result>
struct unary_function
{
typedef Arg argument_type;
typedef Result result_type;
};
template<class Arg1,class Arg2,class Result>
struct binary_function
{
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
template<class T>
struct identity:public unary_function<T,T>
{
const T& operator()(const T& x) const{return x;}
};
template <class T>
struct equal_to:public binary_function<T,T,b