哈希表

来源:互联网 发布:ubuntu系统输入法中文 编辑:程序博客网 时间:2024/05/16 05:14

/*
hash在实际工程里是用的很多的,主要是hash提供了O(1)常量的存储和查找时间
那如何自己设计一个hash需要考虑哪些方面了?
hash有2种实现方式,一种是链式的hash,还有一种是开地址hash方面

下面来看看开地址hash如何实现
负载因子 a = n/m  n为元素个数  m为槽个数
在链式hash里a表示在均匀散列的情况下,每个槽存放元素个数,也就是平均找出次数
在开地址hash负载因子a必须少于1,应该n必须小于m。
开地址hash负载因子和平均查找次数关系为
p= 1 /(1-a)
假设 a=0.5  p=2 表示查找一个元素平均为2次
     a=0.8  p=5 表示查找一个元素平均为5次
     a=0.95 p=20  表示查找一个元素平均为20次

 可以看出 a越接近1 p越大。所以一般呀保证a<0.5

 哈希函数的选择
 h(k)=x
 k为key可以为int或者string类型
 m为槽的大小,m必须素数,在就是考虑实际需要多少空间 比如可能有2000个元素,可以选择m=1699
 这样负载因子a=2000/1699=1.17比较合适
 通常的哈希函数使用取模法 h(k)=k % m
 使用双散列哈希较少冲突 h(k,i)=(k % m + (i +(k % m1))) % m   //m1选择一个比m略少的值 比如m1=m-3
*/
template<class T>
struct CHashPair
{
    T m_data;
    int key;
    CHashPair()
    {
        key = 0;
    }
    CHashPair(const CHashPair& from)
    {
        if (this == &from)
        {
            return *this;
        }
        m_data = from.m_data;
        key = from.key;
    }
};

template<class T,int size>
class CHash
{
 
public:
    CHash(){}
    void Init()
    {
        for (int i=0;i<m_size;++i)
        {
            mb[i].key = 0;
        }
    }
    T* Find(int key)
    {
        for (int i=0;i<m_size;++i)
        {
            int h = HashFunction(key,i);
            CHashPair<T>& Pair = mb[h];
            if (Pair.key == key)
            {
                return &Pair.m_data;
            }
            return NULL;
        }
        return 0;
    }
    bool Insert(const CHashPair<T>& Pair)
    {  
        T* data = Find(Pair.key);
        if (0 != data)
        {
            return false;
        }
        for (int i=0;i<size;++i)
        {
            int h = HashFunction(Pair.key,i);
            CHashPair<T>& Pa = mb[h];
            if (0 == Pa.key)
            {
                Pa.key = Pair.key;
                Pa.m_data = Pair.m_data;
                break;
            }
        }
     
        return true;
    }

    void Remove(int key)
    {
        T* data = Find(key);
        if (0 != data)
        {
            return;
        }
        for (int i=0;i<size;++i)
        {
            int h = HashFunction(key,i);
            CHashPair<T>& Pa = mb[h];
            if (key== Pa.key)
            {
                Pa.key = 0;
                break;
            }
        }
    }
private:
    int HashFunction(int key,int i)
    {
        int h = 0;
        h = (key % size + (i + (key % size - 3))) % size;
        return h;
    }
private:
   
    int m_size;
    CHashPair<T> mb[size];
};

 

int _tmain(int argc, _TCHAR* argv[])
{
 
  CHash<int,1699> hash; 
  CHashPair<int> Pair;
  Pair.key = 1005;
  Pair.m_data = 10;
  hash.Insert(Pair);
  int* value = hash.Find(1005);

}

 

原创粉丝点击