哈希表

2017-07-28 16:01:16

writer:pprp

哈希表:通过节点储存位置和其关键字建立某种直接关系,使得查找的时候无需作比较或者做很少次数的比较就能找到相应的记录;

哈希函数的几种构造方法:

  1. 数学分析法:分析一组数据,比如一组员工的出生年月日,这时我们发现出生年月日的前几位数字大体相同,这样的话,出现冲突的几率就会很大,但是我们发现年月日的后几位表示月份和具体日期的数字差别很大,如果用后面的数字来构成散列地址,则冲突的几率会明显降低。因此数字分析法就是找出数字的规律,尽可能利用这些数据来构造冲突几率较低的散列地址。
  2.  除留余数法:取关键字被某个不大于散列表表长m的数p除后所得的余数为散列地址。即 H(key) = key MOD p,p<=m。不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。对p的选择很重要,一般取素数或m,若p选的不好,容易产生同义词。
  3. 直接寻址法:取关键字或关键字的某个线性函数值为散列地址。即H(key)=key或H(key) = a·key + b,其中a和b为常数(这种散列函数叫做自身函数)。若其中H(key)中已经有值了,就往下一个找,直到H(key)中没有值了,就放进去。

自己制定规则的哈希表

代码如下:

//d = H(K) = 3K%11
//d = (d+(7K%10)+1)%11

#include <iostream>

using namespace std;

const int M = 11;
const int N = 7;

struct term
{
    int key;  //关键字值
    int si;  //散列次数
};

struct term hashlist[M+1];
int i,address,sum,d,x[N+1];
float average;

int main()
{
    for(i=1; i<=M; i++)
    {
        hashlist[i].key=0;
        hashlist[i].si=0;

    }
    x[1]=22,x[2]=41,x[3]=53,x[4]=46,x[5]=30,x[6]=13,x[7]=1;
    
    for(i=1;i<=N;i++)
    {
          sum=0;
          address=(3*x[i])%11;
          d=address;
          if(hashlist[address].key==0)    //没有冲突
          {
                hashlist[address].key = x[i];
                hashlist[address].si = 1;
          }                 
          else
          {
                do
                {
                      d = (d+(x[i]*7)%10+1)%11;
                      sum+=1;
                }while(hashlist[d].key!=0);
                hashlist[d].key = x[i];
                hashlist[d].si = sum+1;
          }
    }
    
    cout << "哈希列表:    ";
    for(i=0;i<M;i++)
    {
          cout.width(4);
          cout << i;
    }
    cout << endl;
    cout << "哈希表关键字: ";
    for(i=0;i<M;i++)
    {
          cout.width(5);
          cout <<hashlist[i].key;
    }
    cout << endl;
    cout <<"搜索长度:   ";
    for(i=0;i<M;i++)
    {
          cout.width(5);
          cout <<hashlist[i].si;
    }
    cout << endl;
    average=0;
    for(i=0;i<M;i++)
      average+=hashlist[i].si;
    average/=N;
    cout <<"平均搜索长度为: "<<average<<endl;
    return 0;
}

 

转载于:https://www.cnblogs.com/pprp/p/7250868.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值