哈希表

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了哈希表相关的知识,希望对你有一定的参考价值。

/****************
编译环境:   vs2012
注意在线编程编译不了

*****************/
#include<iostream>
#include<vector>
#include<string>
using namespace std;
template<class K,class V>
struct kv
{
    K _key;
    V _value;
    kv<K, V>* _next;
    kv(){}
    kv(const K& key,const V& value)
        :_key(key)
        , _value(value)
        , _next(NULL)
    {}
};
 
template<class K>
struct HashFuncDefault
{
    size_t operator()(const K& key)
    {
        return key;
    }
};
static size_t BKDRHash(const char * str)
{
    unsigned int seed = 131; // 31 131 1313 13131 131313
    unsigned int hash = 0;
    while (*str)
    {
        hash = hash * seed + (*str++);
    }
    return (hash & 0x7FFFFFFF);
}
   //模板特化
template<>
struct HashFuncDefault<string>
{
    size_t operator()(const string& st)
    {
        return BKDRHash(st.c_str());
    }
};
template<>
struct HashFuncDefault<void*>
{
    size_t operator()( void* st)//for test online ,not const
    {
         
        int value = (int)(&st);
        return value&0x7fffffff;  
  }
};
//1
template<class K,class V>
class HashTableBucket
{
public:
    HashTableBucket()
        :_size(0)
    {}
    HashTableBucket(const HashTableBucket&  hs)
    {
        _size = hs._size;
        _table.resize(hs._table.size());
        _Copy(hs);
    }
    HashTableBucket<K, V>& operator=(HashTableBucket<K, V> hs)
    {
        hs._table.swap(_table);
        swap(_size, hs._size);
        return *this;
    }
    ~HashTableBucket()
    {
        Clear();
        _size = 0;
    }
    void Clear()
    {
        for (int i = 0; i < _table.size(); ++i)
        {
            kv<K, V>* cur = _table[i];
            kv<K, V>* del = NULL;
 
            while (cur)
            {
                del = cur;
                cur = cur->_next;
 
                delete del;
            }
            _table[i] = NULL;
        }
    }
 
    bool Insert(const K& key, const V& value)
    {
        if (_size == _table.size())//平均每个上面都有数据,扩容
        {
            size_t capacity = _CheckCapacity();
            vector<kv<K, V>*> tmp;
            tmp.resize(capacity);
            for (int i = 0; i < _table.size(); ++i)
            {
                kv<K, V>* cur = _table[i];
                kv<K, V>*pre = NULL;
                while (cur)
                {
                    pre = cur;
                    cur = cur->_next;
                    size_t index = _HashFunc(pre->_key, tmp.size());
                    pre->_next = tmp[index];
                    tmp[index] = pre;
                }
            }
            _table.swap(tmp);
        }
        size_t index = _HashFunc(key, _table.size());
        kv<K, V>* cur = _table[index];
        while (cur)
        {
            if (cur->_key == key)
                return false;
            cur = cur->_next;
        }
        //头插方便
        kv<K, V>* tmp = new kv<K, V>(key, value);
        tmp->_next = _table[index];
        _table[index] = tmp;
        ++_size;
    }
    kv<K, V>* Find(const K& key)
    {
        size_t index = _HashFunc(key, _table.size());
        kv<K, V>* cur = _table[index];
        while (cur)
        {
            if (cur->_key == key)
                return cur;
            cur = cur->_next;
        }
        return NULL;
    }
    bool Remove(const K& key)
    {
        size_t index = _HashFunc(key, _table.size());
        kv<K, V>* cur = _table[index];
        kv<K, V>* prev = NULL;
        while (cur&&cur->_key != key)
        {
            prev = cur;
            cur = cur->_next;
        }
        if (cur == NULL)
            return false;
        else
        {
            if (cur == _table[index])
                _table[index] = cur->_next;
            else
            {
                if (cur->_next)
                    prev->_next = cur->_next;
                else
                    prev->_next = NULL;
            }
            delete cur;
            --_size;
 
        }
    }
    void Print()
    {
        for (int i = 0; i < _table.size(); ++i)
        {
            kv<K, V>* cur = _table[i];
			 cout<<i<<":";

       while (cur)
            {
                     cout <<"("<<cur->_key<<","<<cur->_value<<")-->";
                cur = cur->_next;
            }
            cout << "NULL" << endl;
        }
	}
       
protected:
    void _Copy(const HashTableBucket&  hs)
    {
        for (int i = 0; i < hs._table[i].size(); ++i)
        {
            kv<K, V>* cur = hs._table[i];
            while (cur)
            {
                kv<K, V>* tmp = new kv<K, V>(cur->_key, cur->_value);
                tmp->_next = _table[i];
 
                _table[i] = tmp;
                cur = cur->_next;
            }
        }
    }
    size_t _CheckCapacity()
    {
          const int _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
        };
 
        size_t i = 0;
        for (; i < _PrimeSize; ++i)
        {
            if (_PrimeList[i]>_size)
                return _PrimeList[i];
        }
        return  _PrimeList[_PrimeSize];
    }
 
    size_t _HashFunc(const K& key, size_t capacity)
    {
        return HashFuncDefault<K>()(key) % capacity;
    }
protected:
    vector<kv<K, V>*> _table;
    size_t _size;
};
//2
void  test()
{
    HashTableBucket<int, char> hx;
    hx.Insert(1, ‘A‘);
    hx.Insert(2, ‘B‘);
    hx.Insert(54, ‘C‘);
    hx.Insert(10, ‘D‘);
    hx.Insert(12, ‘E‘);
    hx.Insert(106, ‘F‘);
    hx.Print();
    hx.Remove(97);
    hx.Remove(98);
    hx.Print();
}
int main()
{
test();
return 0;
}

技术分享

以上是关于哈希表的主要内容,如果未能解决你的问题,请参考以下文章

哈希表、哈希算法、一致性哈希表

哈希表(JavaScript实现)

❤️数据结构入门❤️(1 - 8)- 哈希表

哈希表与哈希(Hash)算法

iOS中的哈希表

哈希表—哈希函数的设计