zoukankan      html  css  js  c++  java
  • 哈希桶的实现

    #pragma once
    #include<vector>

    template<class K>
    struct __HashFunc
    {
        size_t operator()(const K&key)
        {
            return key;
        }
    };

    template<>
    struct __HashFunc<string>   //特化
    {
        static size_t BKDRHash(const char*str)    //BKDRHash算法
        {

            unsigned int seed = 131;// 31 131 1313 13131 131313
            unsigned int hash= 0;
            while (*str)
            {
                hash = hash*seed + (*str++);
            }
            return(hash & 0x7FFFFFFF);
        }

        size_t operator()(const string& str)
        {
            return BKDRHash(str.c_str());
        }
    };

    template<class K,class V>
    struct KVNode
    {
        K _key;
        V _value;
        KVNode<K, V>* _next;

        KVNode(const K& key, const V& value)
            :_key(key)
            , _value(value)
            , _next(NULL)
        {}
    };
    template<class K, class V, template<class> class HashFunc = __HashFunc>
    class Hash
    {
    public:
          typedef KVNode<K, V> Node;
        Hash()     //构造函数
            :_size(0)
        {}

        ~Hash()     //析构函数
        {
            Clear();
        }

        Hash(const Hash& ht)    //拷贝构造函数
        {
            Copy(ht);
        }

        Hash& operator=(const Hash&ht)      //赋值运算符的重载
        {
            if (this != &ht)
            {
                Clear;
                Copy(ht);
            }
            return *this;
        }

        bool Insert(const K& key,const V& value)   //插入节点
        {
            _CheckSize();     //检查容量,看是否需要扩容
            size_t index = _HashFunc(key,_tables.size());
            if (Find(key))       //如果有这个值则说明不需要插入
                return false;
           
            //单链表的头插
            Node* head = _tables[index];
            Node* tmp = new Node(key, value);
            tmp->_next =head;
            _tables[index] = tmp;
            ++_size;
            return true;
        }

        //bool Insert(const K& key, const V&value)
        //{
        //    _CheckSize();
        //    size_t index = _HashFunc(key, _tables.size());
        //    Node*begin = _tables[index];
        //    while (begin)
        //    {
        //        if (begin->_key== key)
        //        {
        //            return false;
        //        }
        //        begin = begin->_next;
        //    }
        //    Node* head = _tables[index];
        //    Node* tmp = new Node(key, value);   //头插
        //    tmp->_next = head;
            /*_tables[index] = tmp;
            ++_size;
            return true;
        }*/

        /*bool Remove(const K& key)
        {
            size_t index = _HashFunc(key,_tables.size());
            Node* cur = _tables[index];
            Node* prev = NULL;
            while (cur)
            {
                if (cur->_key == key)
                {
                    if (prev == NULL)
                        _tables[index] = cur->_next;
                    else
                        prev->_next = cur->_next;
                
                    delete cur;
                    --_size;
                    return true;
                }    
                prev = cur;
                cur = cur->_next;
            }
            return false;
        }*/

        bool Remove(const K& key)    //删除节点的函数
        {
            size_t index = _HashFunc(key, _tables.size());
            Node* cur = _tables[index];
            if (cur == NULL)
                return false;

            if (cur->_key == key)   //key为桶的头结点
            {
                _tables[index] = cur->_next;
                delete cur;
                --_size;
                return true;
            }

            Node* prev = cur;  //key为桶的中间节点
            cur = cur->_next;
            while (cur)
            {
                if (cur->_key == key)
                {
                    prev->_next = cur->_next;
                    delete cur;
                    --_size;
                    return true;
                }
                prev = prev;
                cur = cur->_next;
            }
            return false;
        }

        Node* Find(const K& key)    //查找节点
        {
            size_t index = _HashFunc(key,_tables.size());
            Node* cur = _tables[index];
            while (cur)
            {
                if (cur->_key == key)
                    return cur;
                cur = cur->_next;
            }
            return NULL;
        }

        void Print()    //打印哈希桶
        {
            cout << "capacity" << "    " << "size" << ":" << _tables.size() << "   " << _size << endl;
            for (size_t i = 0; i < _tables.size(); ++i)
            {
                Node* cur = _tables[i];
                if (cur == NULL)
                {
                    continue;
                }
                //cout << "[" << i << "]" << "    ";
                printf("【%d】", i);
                while (cur)
                {
                    cout << "{" << cur->_key << "," << cur->_value << "}->";
                    cur = cur->_next;
                }
                cout << "NULL" << endl;
            }
        }
    //protected:
        void _CheckSize()     //检查容量,如果需要扩容就进行扩容
        {
            if (_size == 0 || _size == _tables.size())   
            {
                size_t capacity = _GetnextPrime(_size);
                vector<Node*> Hashtable;
                Hashtable.reserve(capacity);
                Hashtable.assign(capacity, 0);
                for (size_t i = 0; i < _tables.size(); ++i)
                {
                    Node* begin = _tables[i];
                    while (begin)
                    {
                        Node* tmp = begin;
                        begin = begin->_next;

                        size_t index = _HashFunc(tmp->_key,capacity);

                        Node* head = Hashtable[index];
                        tmp->_next = head;
                        Hashtable[index] = tmp;
                    }
                }
                _tables.swap(Hashtable);
            }
        }

        size_t _GetnextPrime(size_t num)
        {
            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
            };

            for (size_t i = 0; i < _Primesize; ++i)
            {
                if (_PrimeList[i]>num)
                {
                    return _PrimeList[i];
                }
                return _PrimeList[_Primesize - 1];
            }
        }

        size_t _HashFunc(const K& key,size_t capacity)
        {
            return HashFunc<K>()(key) %capacity;
        }

        void Clear()   //素组中的元素是指针,因此要特别注意先释放每个节点下的单链表,否则造成内存泄漏
        {
            for (size_t i = 0; i < _tables.size(); ++i)
            {
                Node* cur = _tables[i];
                while (cur)
                {
                    Node* del = cur;
                    cur = cur->_next;
                    delete del;
                }
                _tables[i] = NULL;
            }
        }

        void Copy(const Hash& ht)     //拷贝函数
        {
            _tables.resize(ht._tables.size());
            for (size_t i = 0; i < _tables.size(); ++i)
            {
                Node* cur = ht._tables[i];
                while (cur)
                {
                    Node* newCur = new Node(cur->_key, cur->_value);
                    newCur->_next = _tables[i];
                    _tables[i] = newCur;
                    cur = cur->_next;
                }
            }
        }
    protected:
        vector<Node*> _tables;
        size_t _size;
    };

  • 相关阅读:
    黄聪:robots.txt一分钟教程
    黄聪:C#获取系统中的所有字体
    黄聪:C#下如何实现服务器+客户端的聊天程序
    黄聪:C#截取DOS命令输出流取得网卡MAC地址
    黄聪:选择适当的关键词
    黄聪:C#的Main(String[] args)参数输入问题
    黄聪:C#正则表达式整理备忘
    黄聪:【强烈推荐】搜索引擎排名决定一切吗!
    黄聪:第2章 并发操作的一致性问题 (2)
    黄聪:VS2008 "LIB 环境变量" 无效解决方案
  • 原文地址:https://www.cnblogs.com/qingjiaowoxiaoxioashou/p/6032600.html
Copyright © 2011-2022 走看看