noj23构造哈希表

在这里插入图片描述
哈希表介绍
在面前讨论的各种结构(线性表、树)中,记录在结构中的相对位置是随机的,和记录的关键字之间不存在确定的关系。因此,在结构中查找记录时需进行一系列和关键字的比较。这一类查找方法建立在“比较”的基础上。在顺序查找时,比较的结果为“=”与“≠”两种可能;在折半查找、二叉排序树查找,比较的结果为“<”、“=”和“>”三种可能。查找的效率依赖于查找过程中所进行的比较次数。

哈希表的概念
在查找时,我们理想的情况是希望不经过任何比较,一次存取便能得到所查记录,那就必须在记录的储存位置和它的关键字之间建立一个确定的对应关系f,使每个关键字和结构中一个唯一的储存位置相对应。因而在查找时,只要根据这个对应关系f找到给定值k得像f(k)。若结构中存在关键字和k相等的记录,则必定在f(k)的储存位置上,由此,不需要进行比较便可直接取得所查记录。在此,我们称这个对应关系f为散列函数,又称为哈希(Hash)函数,按这个思想采用散列技术将记录存储在一块连续的存储空间中,这块连续存储空间称为散列表或哈希表

哈希函数的构造方法

构造哈希函数的方法撒很多。在介绍各种方法之前,首先需要明确什么是“好”的哈希函数。

若对于关键字集合中的任何一个关键字,经哈希函数映像到地址集合中任何一个地址的概率是相等的。则称此类哈希函数为均匀的(Uniform)哈希函数。换句话说,就是是关键字经过哈希函数得到一个“随机的地址”,以便使一组关键字的哈希地址均匀分布在整个地址区间中,从而减少冲突。

原文链接:https://blog.csdn.net/m0_56477185/article/details/123119892

线性探测再散列法
基于线性探测再散列法的Hash表的“查找成功的ASL”和“查找不成功的ASL”
ASL指的是 平均查找时间

关键字序列:(7、8、30、11、18、9、14)

散列函数:
H(Key) = (key x 3) MOD 7

装载因子:
0.7

处理冲突:线性探测再散列法

查找成功的ASL计算方法:

因为现在的数据是7个,填充因子是0.7。所以数组大小=7/0.7=10,即写出来的散列表大小为10,下标从0~9。
第一个元素7,带入散列函数,计算得0。
第二个元素8,带入散列函数,计算得3。
第三个元素30,带入散列函数,计算得6。
第四个元素11,带入散列函数,计算得5。
第五个元素18,带入散列函数,计算得5;此时和11冲突,使用线性探测法,得7。
第六个元素9,带入散列函数,计算得6;此时和30冲突,使用线性探测法,得8。
第七个元素14,带入散列函数,计算得0;此时和7冲突,使用线性探测法,得1。
所以散列表:

地址 0 1 2 3 4 5 6 7 8 9
key 7 14 8 11 30 18 9
所以查找成功的计算:
如果查找7,则需要查找1次。
如果查找8,则需要查找1次。
如果查找30,则需要查找1次。
如果查找11,则需要查找1次。
如果查找18,则需要查找3次:第一次查找地址5,第二次查找地址6,第三次查找地址7,查找成功。
如果查找9,则需要查找3次:第一次查找地址6,第二次查找地址7,第三次查找地址8,查找成功。
如果查找地址14,则需要查找2次:第一次查找地址0,第二次查找地址1,查找成功。
所以,ASL=(1+2+1+1+1+3+3)/ 7=12/ 7

原文链接:https://blog.csdn.net/dongfei2033/article/details/80655111

#include <stdio.h>
#include <stdlib.h>

typedef struct HashElem
{
    int key;//位置
    int val;//值
    int stat;//状态
}HashElem;
void InitHash(HashElem data[])
{
    for(int i=0;i<100;i++)
    {
        data[i].key=-1;//位置
        data[i].val=-1;//值
        data[i].stat=-1;//状态为空
    }
}
void Hash(HashElem data[],int num,int a[])
{

    for(int i=0;i<num;i++)
    {
        int temp;
        int k=1;
        temp=3*a[i]%11;
        if(data[temp].stat==1)//发生冲突向后移动
        {
           while(data[temp+k].stat!=-1) k++;
           data[temp+k].key=temp+k;
           data[temp+k].stat=1;
           data[temp+k].val=a[i];
        }
        else
        {
           data[temp].key=temp;
           data[temp].stat=1;
           data[temp].val=a[i];
        }
    }
}
//计算平均查找次数
int AverageLength(HashElem data[],int num,int a[])
{
    int all=0;
    for(int i=0;i<num;i++)
    {
        int p=1;
        if(data[3*a[i]%11].val==a[i])
        {
            all+=p;
        }
        else
        {
            while(data[(3*a[i]%11)+p].val!=a[i])
            {
               p++;
            }
            all=all+p+1;
        }
    }
    return all/num;
}
int main()
{
    int a[8]={22,41,53,46,30,13,01,67};
    HashElem data[100];
    InitHash(data);
    Hash(data,8,a);
    int ans=AverageLength(data,8,a);
    printf("%d",ans);
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值