哈希算法实例

本程序可以将test.txt文件中的记录按key值存储,然后可以快速查找。原理就像数组下表定位一样,只不过,哈希定位是通过key来定位,这个key是通过哈希函数计算得到的,是一个唯一的值。当然有时会得到重复的key值,那么这是就得解决冲突,典型算法是:用线性补偿探测处理冲突,并处理表溢出。如下面的语句。
        k = 0;
       do {
           l = (l+17) % m;
       } while(ht[l]!="" && ++k<=ht.size());
       if (ht[l] == "")
            ht[l]= name;
       else
       if (k>ht.size()) {
          cout << "哈希表溢出!" << endl;
          overflowBucket.push_back(name);
       }
完整源码如下:
#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#ifdef WIN32
#define TEST_FILE   "d:\\work\\proc\\stl\\stl01\\test.txt"
#else
#define TEST_FILE   "/tmp/test.txt"
#endif

class hashvector
{
private:
 vectorht;
 vectoroverflowbucket;
 size_t n;
 size_t m;
public:
    hashvector(vectornamelist,int mo);
    // 返回表长
    size_t size() const { return m; }
    // 返回表大小
    size_t  table_size()  const { return n; }
    // 返回装填因子
    float load_factor() const { return float(table_size())/size(); }
    // 哈希表插入操作
    void insert(vector& ht,
                  vector& overflowBucket, string name);
    // 哈希表查找操作
    void search(string name);
    // 输出表
    void print_table();
private:
 size_t mid(size_t s);
 size_t hstr(const string& name);
};
hashvector::hashvector(vectornamelist,int m0):m(m0)
{
 n=namelist.size();
 ht.resize(m);
 for(size_t i=0;i<n;i++)
 {
  insert(ht,overflowbucket,namelist[i]);
 }
}
// 首先将参数s平方,然后取其各位数字并保存到数组a,最后返回第4、5位数
size_t hashvector::mid(size_t s)
{
   int i=0, a[10];
   size_t d = 1, s0;
   s0 = s*s;
   while(s0>d) d *= 10;
   d /= 10;
   while(d != 0) {
      a[i++] = s0/d;
      s0 = s0%d;
      d = d/10;
   }
   return (a[3]*10+a[4]);
}
size_t hashvector::hstr(const string& name)
{
    // 累加name的ASCII码
    size_t sum = 0, j = 0;
    while(j<name.size()) {
       sum += name[j];  j++;
    }
    return sum;
}
void hashvector::insert(vector& ht,
                        vector& overflowBucket, string name)
{
    size_t  k, s, l;
    // 用除留余数法构造哈希函数
    s = hstr(name);        // 见7.4.2字符串哈希函数
    l = mid(s) % m;         // 除留余数法计算模块
    if (ht[l]=="")
       ht[l] = name;
    else {
       // 用线性补偿探测处理冲突,并处理表溢出
       k = 0;
       do {
           l = (l+17) % m;
       } while(ht[l]!="" && ++k<=ht.size());
       if (ht[l] == "")
            ht[l]= name;
       else
       if (k>ht.size()) {
          cout << "哈希表溢出!" << endl;
          overflowBucket.push_back(name);
       }
    }
}
// 在哈希表中查找指定的姓名
void hashvector::search(string name)
{
    size_t l;
    bool found = false;
    // 计算哈希函数
    size_t s = hstr(name);
    l = mid(s) % m;
    if (ht[l]==name) {
       cout << name << "已找到!在" << l << "号纪录\n";
       found = true;
    }
    int k = 0;
    while (ht[l]!=name && ht[l]!="" && ++k<=ht.size()) {
        // 线性补偿探测
        l = (l+17) % m;
        if (ht[l]==name && !found) {
          cout << name << "已找到!在" << l << "号纪录\n";
          found = true;
          break;
        }
    }
    if(k>ht.size())
       for (size_t i=0; i<overflowbucket.size(); i++)
           if(overflowbucket[i]==name) {
              cout << name << "已找到!在溢出桶" << i << "号纪录\n";
              found = true;
              break;
           }
    if (!found)
       cout << name << "未找到!\n";
}
void hashvector::print_table()
{
    // 显示建立的哈希表
    size_t j, l;
    cout << "**************************   当前哈希表   *************************\n";
    cout << " 编号                       列信息\n";
  //  j = 0;
    for (l=0; l<m; l++)="" {
       if (ht[l] != "") {
       cout << setw(4) << l << setw(25) << ht[l] << "\t";
         // j++;
       //if ((j+1) % 3==1)
             cout << endl;
    }
   }
   cout << "\n总人数是: " << table_size() << endl;
   cout << size() << " 个槽已被占用\n" ;
   cout << "装填因子是: " << load_factor() << endl;
}
int main(void)
{
 vectornamelist;
 ifstream ifs(TEST_FILE);
 if (!ifs)
 {
  cerr<<"error open file!"<<endl;
  getchar();
  exit(0);
 }
 int n=35;
 int cnt=0;
 string name;
 //string name2;
 while(ifs>>name  && cnt++<n)
 {
  namelist.push_back(name);
  //namelist.push_back(name2);
    }
    ifs.close();
 hashvector table(namelist,57);
    
 table.print_table();
 name="hhhh";
 table.search(name); 
 getchar();
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值