zoukankan      html  css  js  c++  java
  • hashtable的C++实现

    hashtable的C++实现,使用两种常用的解决冲突的方式,使用时需要自己提供针对HashedObj的hash函数。

    1、分离连接法(separate chaining)

    #include <vector>
    #include <list>
    using namespace std;
    
    template <typename HashedObj>
    class HashTable
    {
      public:
        explicit HashTable(int size = 101);
    
        void makeEmpty()
        {
            for(int i = 0; i < theLists.size(); i++)
                theLists[i].clear();
        }
    
        bool contains(const HashedObj & x) const
        {
            const list<HashedObj> & whichList = theLists[myhash(x)];
            return find(whichList.begin(), whichList.end(), x) != whichList.end();
        }
    
        bool remove(const HashedObj & x)
        {
            list<HashedObj> & whichList = theLists[myhash(x)];
            typename list<HashedObj>::iterator itr = find(whichList.begin(), whichList.end(), x);
            if(itr == whichList.end())
                return false;
            whichList.erase(itr);
            --currentSize;
            return true;
        }
    
        bool insert(const HashedObj & x)
        {
            list<HashedObj> & whichList = theLists[myhash(x)];
            if(find(whichList.begin(), whichList.end(), x) != whichList.end())
                return false;
            whichList.push_back(x);
            if(++currentSize > theLists.size())
                rehash();
            return true;
        }
    
      private:
        vector<list<HashedObj> > theLists;   // The array of Lists
        int  currentSize;
    
        void rehash()
        {
            vector<list<HashedObj> > oldLists = theLists;
    
            // Create new double-sized, empty table
            theLists.resize(2 * theLists.size());
            for(int j = 0; j < theLists.size(); j++)
                theLists[j].clear();
    
            // Copy table over
            currentSize = 0;
            for(int i = 0; i < oldLists.size(); i++)
            {
                typename list<HashedObj>::iterator itr = oldLists[i].begin();
                while(itr != oldLists[i].end())
                    insert(*itr++);
            }
        }
    
        int myhash(const HashedObj & x) const
        {
            int hashVal = hash(x);
    
            hashVal %= theLists.size();
            if(hashVal < 0)
                hashVal += theLists.size();
    
            return hashVal;
        }
    };

    2、使用探测法(probing hash tables)

    template <typename HashedObj>
    class HashTable
    {
      public:
        explicit HashTable(int size = 101) : array(size)
        {
            makeEmpty();
        }
    
        void makeEmpty()
        {
            currentSize = 0;
            for(int i = 0; i < array.size(); i++)
                array[i].info = EMPTY;
        }
    
        bool contains(const HashedObj & x) const
        {
            return isActive(findPos(x));
        }
    
        bool insert(const HashedObj & x)
        {
            // Insert x as active
            int currentPos = findPos(x);
            if(isActive(currentPos))
                return false;
    
            array[currentPos] = HashEntry(x, ACTIVE);
    
            if(++currentSize > array.size()/2)
                rehash();
    
            return true;
        }
    
        bool remove(const HashedObj & x)
        {
            int currentPos = findPos(x);
            if(!isActive(currentPos))
                return false;
            array[currentPos].info = DELETED;
            return true;
        }
    
        enum EntryType { ACTIVE, EMPTY, DELETED };
    
      private:
        struct HashEntry
        {
             HashedObj element;
             EntryType info;
             HashEntry(const HashedObj & e = HashedObj(), EntryType i = EMPTY )
               : element(e), info(i) { }
        };
    
        vector<HashEntry> array;
        int currentSize;
    
        int findPos(const HashedObj & x) const
        {
            int offset = 1;
            int currentPos = myhash(x);
    
            while(array[currentPos].info != EMPTY && array[currentPos].element != x)
            {
                currentPos += offset;  // Compute ith probe
                offset += 2;
                if(currentPos >= array.size())
                    currentPos -= array.size();
            }
            return currentPos;
        }
    
        bool isActive(int currentPos) const
        {
            return array[currentPos].info == ACTIVE;
        }
    
        void rehash()
        {
            vector<HashEntry> oldArray = array;
    
            // Create new double-sized, empty table
            array.resize(2*oldArray.size());
            for(int j = 0; j < array.size(); j++)
                array[j].info = EMPTY;
    
            // Copy table over
            currentSize = 0;
            for(int i = 0; i < oldArray.size(); i++)
                if(oldArray[i].info == ACTIVE)
                    insert(oldArray[i].element);
        }
    
        int myhash(const HashedObj & x) const;
    };
  • 相关阅读:
    drf中APIView源码分析
    将orm中模型类对象转化为字典,简单粗暴的方法
    python中uuid的使用
    每日作业 7/3
    传输文件到docker容器
    mysql 常用选项
    mysql基本语句
    mysql数据库的基本操作增删改查
    docker service的常用操作
    centos7主机重命名
  • 原文地址:https://www.cnblogs.com/luxiaoxun/p/2667425.html
Copyright © 2011-2022 走看看