【数据结构实训】哈希表设计

这篇具有很好参考价值的文章主要介绍了【数据结构实训】哈希表设计。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

[问题描述]

针对某个集体中人名设计一个哈希表,使得平均查找长度不超过2,并完成相应的建表和查表程序。

[基本要求]

假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。

[测试数据]

取自己周围较熟悉的30个人名。

[选作内容]

(1) 从教科书上介绍的集中哈希函数构造方法中选出适用者并设计几个不同的哈希函数,比较他们的地址冲突率(可以用更大的名字集合作实验)。
(2) 研究这30个人名的特点,努力找一个哈希函数,使得对于不同的拼音名一定不发生地址冲突。
(3)在哈希函数确定的前提下尝试各种不同处理冲突的方法,考察平均查找长度的变化和造好的哈希表中关键字的聚集性。

[代码实现]

/*
0!='0'
*/
#include<queue>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
#define scnaf scanf
#define ll long long
const int N=1000;
int n=30,l=0x3f3f3f3f,r=0,flag,cut=0;
char s[N][20],x[20];
int hashnum1(int k)//1.hash函数|取余法
{
    r=max(r,k%31+1);
    l=min(l,k%31+1);
    return k%31+1;
}
int hashnum2(int k)//2.hash函数|数字分析法
{
    int p,i=1,t=0;
    while(k)
    {
        p=k%10;
        if(i<3)
            t+=p*i++;
        else t+=p*i--;
        k/=10;
    }
    r=max(r,t);//
    l=min(l,t);
    return t;//
}
int hashnum3(char asc[])//直接定址法,该法针对所给30个人名样本不产生冲突
{
    int p=0,i,j;
    for(i=0,j=0;asc[i];i++,j++)
        p+=asc[i]*i;
    p=(p/1000*10+p/100%10)*(p/10%10*10+p%10);
    p/=10;
    r=max(r,p);
    l=min(l,p);
    return p;
}
int slove(char asc[],int f)//分配哈希函数
{
    int ans=0,i;
    for(i=0;asc[i];i++)
        ans+=asc[i];
    switch(f)
    {
        case 0:return ans;
        case 1:return hashnum1(ans);
        case 2:return hashnum2(ans);
        case 3:return hashnum3(asc);
    }
}
/*****以下链地址法解决冲突******/
struct Node
{
    char key[20];//名字
    struct Node *next;
};
struct Hash
{
    int sum;//冲突次数
    struct Node *data;//结点
}h[N];
void init()//malloc->free
{
    struct Node *q,*p;
    for(int i=l;i<=r;i++)
    {
        h[i].sum=0;
        p=h[i].data;
        while(p!=NULL)
        {
            q=(*p).next;
            free(p);
            p=q;
        }
    }
    for(int i=l;i<=r;i++)
        h[i].data=NULL;
    l=0x3f3f3f3f,r=0;
}
void inserthash(int k,char asc[])//插入
{
    struct Node *q;
    q=(struct Node *)malloc(sizeof(struct Node));
    strcpy((*q).key,asc);
    (*q).next=h[k].data;
    h[k].data=q;
    h[k].sum++;
}
int searchhash(int k,char asc[])//查找
{
    struct Node *p=h[k].data;
    int cut=0;
    while(p!=NULL)
    {
        cut++;
        if(strcmp(asc,(*p).key)==0)
            return cut;
        p=(*p).next;
    }
    return 0;
}
void printff()//打印哈希表
{
    printf("哈希表如下所示:\n");
    for(int i=l;i<=r;i++)
    {
        printf("%d",i);
        if(h[i].data!=NULL)
        {
            struct Node *p=h[i].data;
            while(p!=NULL)
            {
                printf(" ->%s",(*p).key);
                p=(*p).next;
            }
        }
        printf("\n");
    }
}
void chongtu()//平均查找长度
{
    int i,k=0;
    for(i=1;i<=n;i++)
        k+=searchhash(slove(s[i],flag),s[i]);
    switch(flag)
    {
        case 1:
        {
            printf("您选择的是取余法,平均查找长度为:%.2lf\n",k*1.0/n);
            return ;
        }
        case 2:
        {
            printf("您选择的是数字分析法,平均查找长度为:%.2lf\n",k*1.0/n);
            return ;
        }
        case 3:
        {
            printf("您选择的是直接定址法,平均查找长度为:%.2lf\n",k*1.0/n);
        }
    }
}
/**********************************/
/*****以下开放地址法解决冲突******/
struct ss
{
    char name[20];
    int length;
    int emp;
}H[N];
void init2()//清零
{
    memset(H,0,sizeof(H));
    l=0x3f3f3f3f,r=0;
}
void inserthash2(int k,char asc[])//插入
{
    int cnt=1,p=1;
    while(H[k].emp)
    {
        if(cnt&1)
            k=(k+p*p)%r;
        else k=(k-p*p)%r,p++;
        cnt++;
    }
    strcpy(H[k].name,asc);
    H[k].length=cnt;
    H[k].emp=1;
}
int searchhash2(int k,char asc[])//查找
{
    int cnt=0,p=1;
    while(H[k].emp)
    {
        cnt++;
        if(strcmp(asc,H[k].name)==0)
            return cnt;
        if(cnt&1)
            k=(k+p*p)%r;
        else k=(k-p*p)%r,p++;
    }
    if(!H[k].emp)
        return 0;
}
void printff2()//打印哈希表
{
    printf("哈希表如下所示:\n");
    for(int i=l;i<=r;i++)
    {
        printf("%d",i);
        if(H[i].emp)
            printf(" ->%s %d",H[i].name,H[i].length);
        printf("\n");
    }
}
void chongtu2()//平均查找长度
{
    int i,k=0;
    for(i=1;i<=n;i++)
        k+=searchhash2(slove(s[i],flag),s[i]);
    switch(flag)
    {
        case 1:
        {
            printf("您选择的是取余法,平均查找长度为:%.2lf\n",k*1.0/n);
            return ;
        }
        case 2:
        {
            printf("您选择的是数字分析法,平均查找长度为:%.2lf\n",k*1.0/n);
            return ;
        }
        case 3:
        {
            printf("您选择的是直接定址法,平均查找长度为:%.2lf\n",k*1.0/n);
        }
    }
}
/*********************************/

int main()
{
    int i,j,k,p,v;
    printf("请输入姓名:\n");
    for(i=1;i<=n;i++)
        scnaf("%s",s[i]);
    printf("\n请选择冲入处理方式:\n 1.链地址法\n 2.开放定址法\n");
    scanf("%d",&v);
    if(v&1)
    {
        printf("\n您选择的是链地址法\n");
        printf("\n请选择哈希函数:\n 1.取余法\n 2.数字分析法\n 3.直接定址法\n");
        scanf("%d",&flag);
        init();
        for(i=1;i<=n;i++)
        {
            k=slove(s[i],flag);
            inserthash(k,s[i]);
        }
        switch(flag)
        {
            case 1:printf("\n您选择的是取余法\n");break;
            case 2:printf("\n您选择的是数字分析法\n");break;
            case 3:printf("\n您选择的是直接定址法\n");break;
        }
        while(1)
        {
            printf("\n请输入:\n 0.退出\n 1.插入名字\n 2.查找名字\n 3.打印哈希表\n 4.平均查找长度\n");
            scnaf("%d",&p);
            if(!p)
            {
                init();
                break;
            }
            switch(p)
            {
                case 1:
                {
                    printf("\n请输入您要添加的名字:\n");
                    scnaf("%s",s[++n]);
                    k=slove(s[n],flag);
                    inserthash(k,s[n]);
                    break;
                }
                case 2:
                {
                    printf("\n请输入您要查找的名字:\n");
                    scnaf("%s",x);
                    k=slove(x,flag);
                    j=searchhash(k,x);
                    if(!j)
                        printf("\n查找失败,请重新输入\n");
                    else printf("\n查找成功,查找长度为:%d\n",j);
                    break;
                }
                case 3:printff();break;
                case 4:chongtu();break;
            }
        }
    }
    else
    {
        printf("\n您选择的是开放定址法\n");
        printf("\n请选择哈希函数:\n 1.取余法\n 2.数字分析法\n 3.直接定址法\n");
        scanf("%d",&flag);
        init2();
        for(i=1;i<=n;i++)
        {
            k=slove(s[i],flag);
            inserthash2(k,s[i]);
        }
        switch(flag)
        {
            case 1:printf("\n您选择的是取余法\n");break;
            case 2:printf("\n您选择的是数字分析法\n");break;
            case 3:printf("\n您选择的是直接定址法\n");break;
        }
        while(1)
        {
            printf("\n请输入:\n 0.退出\n 1.插入名字\n 2.查找名字\n 3.打印哈希表\n 4.平均查找长度\n");
            scnaf("%d",&p);
            if(!p)
            {
                init2();
                break;
            }
            switch(p)
            {
                case 1:
                {
                    printf("\n请输入您要添加的名字:\n");
                    scnaf("%s",s[++n]);
                    k=slove(s[n],flag);
                    inserthash2(k,s[n]);
                    break;
                }
                case 2:
                {
                    printf("\n请输入您要查找的名字:\n");
                    scnaf("%s",x);
                    k=slove(x,flag);
                    j=searchhash2(k,x);
                    if(!j)
                        printf("\n查找失败,请重新输入\n");
                    else printf("\n查找成功,查找长度为:%d\n",j);
                    break;
                }
                case 3:printff2();break;
                case 4:chongtu2();break;
            }
        }
    }
    return 0;
}
/*
int main()
{
    char v[35][20];
    int a[35];
    for(int i=1;i<=n;i++)
        scnaf("%s",v[i]),a[i]=slove(v[i],1);
    sort(a+1,a+n+1);
    for(int i=1;i<=n;i++)
        printf("%d\n",a[i]);
    return 0;
}

/
//29|22-3 31|22-2
/

700~140
yangxinyi
lihaoyu
xuhaidong
songzongzui
wangzongyao
zhangwenqi
liudengtian
huoyuqing
fangyuanyuan
wangweiyi
wangyan
zhoumeichen
chenshuai
hanmeng
liyaran
yuxiaolei
lujiale
shichenghong
liuwanyou
chaiwenli
wanghaozhi
zhaobowen
gaoruiying
lijinfang
sunpeng
sunshanpeng
wanghongyang
xinghaora
qinyichen
xiuyuhang
*/文章来源地址https://www.toymoban.com/news/detail-502832.html

到了这里,关于【数据结构实训】哈希表设计的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【数据结构与算法】哈希表设计(C\C++)

    针对某个集体中人名设计一个哈希表,使得平均查找长度不超过R,并完成相应的建表和查找程序。 假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2。哈希函数用除留余数法构造。用伪随机探测再散列法处理冲突。 取读者周围

    2024年02月04日
    浏览(40)
  • 数据结构学习记录——图应用实例-拯救007(问题描述、解题思路、伪代码解读、C语言算法实现)

    目录 问题描述  解题思路 伪代码  总体算法 DFS算法 伪代码解读 总体算法 DFS算法 具体实现(C语言) 在老电影“007之生死关头”(Live and Let Die)中有一个情节,007被毒贩抓到一个鳄鱼池中心的小岛上,他用了一种极为大胆的方法逃脱 —— 直接踩着池子里一系列鳄鱼的大脑

    2024年02月05日
    浏览(56)
  • 数据结构与算法细节篇之最短路径问题:Dijkstra和Floyd算法详细描述,java语言实现。

    最短路径的算法有两个, Dijkstra算法 和 Floyd算法 。 Dijkstra算法 解决的是 单源 最短路径问题 。 Floyd算法解决的是 多源 最短路径问题,并且可以处理负权图 。 今天要讲的就是Dijkstra算法。 加: feng--Insist (大写的i),进java交流群讨论互联网+技术。可索要PPT等资料。 其他资料

    2024年02月11日
    浏览(33)
  • 全减器---Verilog实现(结构描述,数据流描述,行为描述,层次结构描述)

    全减器真值表—引用知乎:链接: 全减器真值表怎么理解 代码部分 原理图 代码部分 原理图 代码部分 原理图 代码部分 原理图

    2024年02月12日
    浏览(39)
  • Verilog的三种描述方式(结构化描述、数据流描述、行为级描述对电路功能的描述有三种方式:结构化描述、数据流描述、行为级描述

    Verilog的三种描述方式(结构化描述、数据流描述、行为级描述对电路功能的描述有三种方式:结构化描述、数据流描述、行为级描述。三种描述方式抽象级别不同,各有优缺点,相辅相成,需要配合使用。 目录 一、结构化描述 1、概念 2、特点 3、示例 真值表: 电路抽象:

    2024年02月04日
    浏览(55)
  • 数据结构-哈希-哈希表实现

    🚀理想的搜索方法:不经过任何的比较,一次直接从表中得到要搜索的元素。如果构造一种存储结构,通过某种函数使元素的存储位置与其关键码之间能够建立起一一映射的关系,那么在查找的时候就能通过此函数快速的找到该元素。 🚀向该结构中插入元素:根据该元素的

    2024年02月10日
    浏览(26)
  • 【数据结构】哈希底层结构

    目录 一、哈希概念 二、哈希实现 1、闭散列 1.1、线性探测 1.2、二次探测 2、开散列 2.1、开散列的概念 2.2、开散列的结构 2.3、开散列的查找 2.4、开散列的插入 2.5、开散列的删除 3、性能分析  顺序结构以及平衡树中,元素关键码与其存储位置之间没有对应的关系,因此在查

    2024年02月06日
    浏览(35)
  • 「数据结构」哈希表2:实现哈希表

    🎇 个人主页 :Ice_Sugar_7 🎇 所属专栏 :Java数据结构 🎇 欢迎点赞收藏加关注哦! 在讲插入之前需要先了解扩容,因为 插入后载荷因子如果超过阈值,那我们就要扩容,即扩容是插入操作的一部分 扩容后,原先哈希表中的元素的哈希地址会改变。之前会发生哈希冲突的元素

    2024年02月21日
    浏览(30)
  • 【数据结构】哈希表与哈希桶

    👀 樊梓慕: 个人主页  🎥 个人专栏: 《C语言》 《数据结构》 《蓝桥杯试题》 《LeetCode刷题笔记》 《实训项目》 《C++》 《Linux》 《算法》 🌝 每一个不曾起舞的日子,都是对生命的辜负 目录 前言 1.概念 2.哈希冲突 3.解决哈希冲突 3.1闭散列 3.2开散列(哈希桶) 4.模拟实

    2024年03月21日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包