• 散列之分离链接法


     1 #include <vector>
     2 #include <list>
     3 #include <string>
     4 #include <algorithm>
     5 using std::vector;
     6 using std::list;
     7 using std::string;
     8 using std::find;
     9 
    10 int hash(const string &key)
    11 {
    12     int hashVal = 0;
    13 
    14     for(string::size_type i=0; i!=key.size(); ++i)
    15         hashVal += key[i];
    16 
    17     return hashVal;
    18 }
    19 int hash(int key)
    20 {
    21     return key;
    22 }
    23 
    24 template<typename HashedObj>
    25 class HashTable
    26 {
    27     public:
    28         explicit HashTable(int size=101):theLists(size) {}
    29 
    30         bool contains(const HashedObj &x) const
    31         {
    32             const list<HashedObj> &whichList = theLists[myhash(x)];
    33             return find(whichList.begin(), whichList.end(), x)!=whichList.end();
    34         }
    35         void clear()
    36         {
    37             for(int i=0; i<theLists.size(); ++i)
    38                 theLists[i].clear();
    39         }
    40         bool insert(const HashedObj &x)
    41         {
    42             const list<HashedObj> &whichList = theLists[myhash(x)];
    43 
    44             if(find(whichList.begin(), whichList.end(), x)!=whichList.end())
    45                 return false;
    46 
    47             whichList.push_front(x);
    48             ++currentSize;
    49             return true;
    50         }
    51         bool remove(const HashedObj &x)
    52         {
    53             const list<HashedObj> &whichList = theLists[myhash(x)];
    54             list<HashedObj>::iterator it = find(whichList.begin(), whichList.end(), x);
    55 
    56             if(it==whichList.end())
    57                 return false;
    58 
    59             whichList.erase(it);
    60             --currentSize;
    61             return true;
    62         }
    63 
    64     private:
    65         vector<list<HashedObj> > theLists;
    66         int currentSize;
    67 
    68         int myhash(const HashedObj &x) const
    69         {
    70             int hashVal = hash(x);
    71 
    72             hashVal %= theLists.size();
    73             if(hashVal<0)
    74                 hashVal += theLists.size();
    75 
    76             return hashVal;
    77         }
    78 };

     以上是分离链接法的C++实现。

    除了分离链接法以外,还有一些不使用链表的实现散列表的方法,包括线性探测、平方探测、双散列等。

    使用分离链接法,当出现冲突时,直接将新元素插入对应链表即可。不使用链表时,可采用线性探测、平方探测、双散列等技术来处理冲突。

    线性探测&平方探测:h(x) = hash(x)+f(i),其中f(i)分别是i的一次和二次函数。

    双散列:h(x) = hash1(x)+f(i)*hash2(x)。

    另外,宜使散列表大小为素数值,从而使hash值分布更均匀,以减少冲突。

  • 相关阅读:
    PDO如何选择其他数据库的驱动
    PHP里关于时间日期大小写(Y,y,M,m...)
    数据库的基本操作
    数据库--PHP环境搭建
    曾经的中国互联网:多少巨头销声匿迹
    SQL 查找 45道练习题
    关于padding
    Mysql ERROR 1045 (28000): Access denied for user 'root'@'localhost'(using password: YSE)
    centos 格式化硬盘并挂载,添加重启后生效
    windows2003服务器不显示桌面怎么办
  • 原文地址:https://www.cnblogs.com/pczhou/p/4647831.html
Copyright © 2020-2023  润新知