数据结构—Hashtable(闭散列)

来源:互联网 发布:java在线直播平台源码 编辑:程序博客网 时间:2024/05/09 18:26

哈希表是常见数据结构中一种拥有高效插入,高效查找的结构,时间复杂度为O(1)。

闭散列哈希的不足之处就是随着冲突的数据增多,插入的效率也会随之变慢,为了优化闭散列哈希的效率,我们可以采取以下的方式:

>1.当插入的数据占总大小的一定比率的时候,也称负载因子,我们可以对哈希表进行扩容,重新通过哈希函数求得位置插入。
>2.我们可以采用素数表的形式,来减少哈希冲突的可能。
>3.通过更好优化的哈希函数,来减少冲突的可能。

这里写图片描述
每次扩容,带来的也是巨大的开销,首先要开辟新的空间,其次,重新插入需要通过哈希函数重新求得新插入的位置。
1。我们通过对每个哈希节点进行标记,三种标记分别为EMPTY空白,DELETE删除,EXIST存在。分别表示此处没有插入过数据,插入过数据但当前位置数据已经删除,此处存在数据。
2。当我们进行查找的时候,如果前k值通过哈希函数求得位置向后查找,如果为EMPTY则停下,当找到表的尾部,然后从0开始继续查找。
3。当我们插入的时候,同理求得插入位置,如果该位置已经有值,我们向后查找,当遇到EMPTY或者DELETE时,该位置没有数据,在该位置插入。

我们在插入时,通过函数CheckLoadFactor()来检测当前负载因子,当负载因子当到我们设定的比率时,我们采用对哈希表进行扩,扩容的大小为每次素数表中的下一个素数大小。
本次哈希表中的哈希函数,使用的是直接定值法。

#include<iostream>#include<vector>using namespace std;enum condition{    EMPTY,    DELETE,    EXIST,};template<class K, class V>struct Hashnode{    K key;    V value;    condition con;    Hashnode(const K k = K(), const V v = V())        :key(k)        , value(v)        , con(EMPTY)    {}};template<class K>struct HashFun{    size_t operator()(K k)    {        return k;    }};template<class K, class V, class __HashFun = HashFun<K> >class Hashtable{public:    typedef Hashnode<K, V> node;    Hashtable()        :size(0)    {}    Hashtable(const Hashtable& h)        :size(0)    {        for (size_t index = 0; index<h.table.size(); index++)        {            Insert(h.table[index].key, h.table[index].value);        }    }    Hashtable& operator=(Hashtable h)    {        table.swap(h.table);        swap(size, h.size);        return *this;    }    bool Insert(K k, V v)    {        CheckLoadFactor();        size_t index = Hashfun(k);        while (table[index].key = k || (table[index].key = k&&table[index].con != EXIST))        {            if (table[index].con != EXIST)            {                table[index].key = k;                table[index].value = v;                table[index].con = EXIST;                size++;                return true;            }            index++;            if (index>table.size())            {                index = 0;            }        }        return false;    }    size_t Hashfun(const K& k)    {        __HashFun hashfun;        return hashfun(k) % table.size();    }    node* Find(const K& k)    {        size_t index = Hashfun(k);        while (table[index].con != EMPTY)        {            if (table[index].key == k&&table[index].con == EXIST)            {                return &table[index];            }            index++;            if (index>table.size())            {                index = 0;            }        }        return NULL;    }    bool Erase(const K& pos)    {        if (Find(pos) != NULL)        {            Find(pos)->con = DELETE;            size--;            return true;        }        return false;    }private:    void CheckLoadFactor()    {        if (table.size() == 0 || (size * 10 / table.size())>7)        {            table.size() == 0 ? table.resize(7) : Changecapacity();        }    }    void Changecapacity()    {        Hashtable<K, V, __HashFun> newtable;        newtable.table.resize(GetNextPrime(table.size()));        for (size_t index = 0; index<table.size(); index++)        {            if (table[index].con == EXIST)            {                newtable.Insert(table[index].key, table[index].value);            }        }        table.swap(newtable.table);    }    size_t GetNextPrime(size_t pre)    {        const size_t _PrimeSize = 28;        static const unsigned long _PrimeList[_PrimeSize] =        {            53ul, 97ul, 193ul, 389ul, 769ul,            1543ul, 3079ul, 6151ul, 12289ul, 24593ul,            49157ul, 98317ul, 196613ul, 393241ul, 786433ul,            1572869ul, 3145739ul, 6291469ul, 12582917ul, 25165843ul,            50331653ul, 100663319ul, 201326611ul, 402653189ul, 805306457ul,            1610612741ul, 3221225473ul, 4294967291ul        };        for (size_t index = 0; index<_PrimeSize; index++)        {            if (pre<_PrimeList[index])                return _PrimeList[index];        }        return _PrimeList[_PrimeSize - 1];    }private:    vector<node> table;    size_t size;};
原创粉丝点击