zoukankan      html  css  js  c++  java
  • 数据结构实训——哈希表设计

    1 课题描述

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

    2 问题分析和任务定义

    1假设人名为中国人姓名的汉语拼音形式。待填入哈希表的人名共有30个,取平均查找长度的上限为2

    2哈希函数用除留余数法构造,用线性探测再散列法或链地址法处理冲突。

    3 在输入人名过程中能自动识别非法输入,并给与非法输入的反馈信息要求重新输入。

    4)查找成功时,显示姓名及关键字,并计算和输出查找成功的平均查找长度

    3 逻辑设计

    1)数据类型:

    对于名字中包含的信息,名字的拼音使用字符串类型保存,由拼音字母ascll构成的关键字使用整数型保存。对于哈希表所包含的信息,姓名使用字符串类型保存,关键字使用整数型保存,哈希表中的元素使用整数类型保存。

    struct name///名字结构体

    {

        char s[30];

        int v;///ascll码值之和

    } NAME[N];

    struct hashs///哈希表结构体

    {

        char name[30];///名字

        int key;///关键字

        int sum;///哈希表中含有的元素个数

    } HASH[M];

    2)抽象数据类型:

    ADT Hash {

    数据对象DD是具有相同特征的数据元素的集合。各数据元素均含有类型相同,可唯一标识数据元素的关键字。

    数据关系R:数据元素同属一个集合。

    init()

    操作结果:初始化姓名表。

    creathash()

    操作结果:建立哈希表。

    displayhash()

    操作结果:显示哈希表。

    display()

    操作结果:显示姓名表。

    searchhash()

    操作结果:查找姓名。

    }ADT Hash

     

    3)模块功能:

    功能上主要分为初始化姓名表,构建哈希表,显示姓名表,显示哈希表,从哈希表中

    查找姓名这五大功能。其中构建哈希表使用除留余数法构建,并用线性探测再散列的方法解决冲突。

     

    4 详细设计

    {定义相应的存储结构并写出各函数的伪码算法。在这个过程中,要综合考虑系统功能,使得系统结构清晰、合理、简单和易于调试,抽象数据类型的实现尽可能做到数据封装,基本操作的规格说明尽可能明确具体。详细设计的结果是对数据结构和基本操作做出进一步的求精,写出数据存储结构的类型定义,写出函数形式的算法框架}

    const int N=30;

    const int M=50;

    struct name///名字结构体

    {

        char s[30];

        int v;///ascll码值之和

    } NAME[N];

    struct hashs///哈希表结构体

    {

        char name[30];///名字

        int key;///关键字

        int sum;///哈希表中含有的元素个数

    } HASH[M];

    <1>初始化函数:void init()

    读取姓名信息,初始化姓名表。

    <2>创建哈希表函数:void creathash()

    将读取信息建立的姓名表建立哈希表。

    <3>演示哈希表函数:void displayhash()

    打印哈希表中的信息。

    <4>演示姓名表函数:void display()

    打印姓名表中的信息。

    <5>查找哈希表中的姓名函数 void searchhash()

    按照输入的姓名查找其在哈希表中的位置,并打印信息。

     

    5 程序代码

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=30;
    const int M=50;
    struct name///名字结构体
    {
        char s[30];
        int v;///ascll码值之和
    } NAME[N];
    struct hashs///哈希表结构体
    {
        char name[30];///名字
        int key;///关键字
        int sum;///哈希表中含有的元素个数
    } HASH[M];
    void init()///初始化
    {
        int i,j,sum;
        for(i=0; i<N; i++)
        {
            NAME[i].v=0;
        }
        strcpy(NAME[0].s,"chenliang");//陈亮
        strcpy(NAME[1].s,"chenyuanhao");//陈元浩
        strcpy(NAME[2].s,"chengwenliang");//程文亮
        strcpy(NAME[3].s,"dinglei");//丁磊
        strcpy(NAME[4].s,"fenghanzao");//冯汉枣
        strcpy(NAME[5].s,"fuzongkai");//付宗楷
        strcpy(NAME[6].s,"hujingbin");//胡劲斌
        strcpy(NAME[7].s,"huangjianwu");//黄建武
        strcpy(NAME[8].s,"lailaifa");//赖来发
        strcpy(NAME[9].s,"lijiahao");//李嘉豪
        strcpy(NAME[10].s,"liangxiaocong");//梁晓聪
        strcpy(NAME[11].s,"linchunhua");//林春华
        strcpy(NAME[12].s,"liujianhui");//刘建辉
        strcpy(NAME[13].s,"luzhijian");//卢志健
        strcpy(NAME[14].s,"luonan");//罗楠
        strcpy(NAME[15].s,"quegaoxiang");//阙高翔
        strcpy(NAME[16].s,"sugan");//苏淦
        strcpy(NAME[17].s,"suzhiqiang");//苏志强
        strcpy(NAME[18].s,"taojiayang");//陶嘉阳
        strcpy(NAME[19].s,"wujiawen");//吴嘉文
        strcpy(NAME[20].s,"xiaozhuomin");//肖卓明
        strcpy(NAME[21].s,"xujinfeng"); //许金峰
        strcpy(NAME[22].s,"yanghaichun");//杨海春
        strcpy(NAME[23].s,"yeweixiong");//叶维雄
        strcpy(NAME[24].s,"zengwei");//曾玮
        strcpy(NAME[25].s,"zhengyongbin");//郑雍斌
        strcpy(NAME[26].s,"zhongminghua");//钟明华
        strcpy(NAME[27].s,"chenliyan");//陈利燕
        strcpy(NAME[28].s,"liuxiaohui");//刘晓慧
        strcpy(NAME[29].s,"panjinmei");//潘金梅
        for(i=0; i<N; i++)
        {
            sum=0;
            for(j=0; j<strlen(NAME[i].s); j++)
            {
                sum=sum+(NAME[i].s[j]-'a');
            }
            NAME[i].v=sum;///名字字母ascll码之和
        }
    }
    void creathash()///构造哈希表
    {
        int i,j;
        int n,m,counts;
        for(i=0; i<M; i++)
        {
            strcpy(HASH[i].name,"0");
            HASH[i].key=0;
            HASH[i].sum=0;
        }
        for(i=0; i<N; i++)
        {
            counts=1;
            n=(NAME[i].v)%47;
            m=n;
            if(HASH[n].sum==0)///不冲突
            {
                strcpy(HASH[n].name,NAME[i].s);
                HASH[n].key=NAME[i].v;
                HASH[n].sum=1;
            }
            else///如果发生了冲突
            {
                while(1)
                {
                    m=(m+(NAME[i].v%10)+1)%47;
                    counts++;
                    if(HASH[m].key==0)
                    {
                        break;
                    }
                }
                strcpy(HASH[m].name,NAME[i].s);
                HASH[m].key=NAME[i].v;
                HASH[m].sum=counts;
            }
        }
        return ;
    }
    void searchhash()
    {
        char name[30];
        int i,sum,n,m,counts;
        sum=0;
        n=0;
        counts=1;
        printf("请输入要查找人的姓名拼音:
    ");
        scanf("%s",&name);
        for(i=0; i<strlen(name); i++)
        {
            sum+=(name[i]-'a');
        }
        n=sum%47;
        m=n;
        if(strcmp(HASH[n].name,name)==0)
        {
            printf("姓名:%s 关键字:%d 查找长度:1
    ",HASH[n].name,sum);
        }
        else if(HASH[n].sum==0)
        {
            printf("没有找到这条记录!!!
    ");
        }
        else
        {
            while(1)
            {
                m=(m+(sum%10)+1)%47;///哈希函数
                counts++;
                if(strcmp(HASH[m].name,name)==0)
                {
                    printf("姓名:%s 关键字:%d 查找长度:%d
    ",HASH[m].name,sum,counts);
                    break;
                }
                if(HASH[m].key==0)
                {
                    printf("没有找到这条记录!!!
    ");
                    break;
                }
            }
        }
    }
    void displayhash()///演示哈希表
    {
        int i,sum;
        float ave;
        ave=0.0;
        sum=0;
        printf("
    地址	关键字		搜索长度	姓名
    ");
        for(i=0; i<M; i++)
        {
            printf("%d",i);
            printf("	%d",HASH[i].key);
            printf("		%d",HASH[i].sum);
            printf("	%s",HASH[i].name);
            printf("
    ");
        }
        for(i=0; i<M; i++)
        {
            sum+=HASH[i].sum;
        }
        ave=((sum)*1.0)/N;
        printf("
    ");
        printf("平均查找长度ASL(%d)=%.3lf
    ",N,ave);
        return ;
    }
    void display()
    {
        int i;
        for(i=0; i<30; i++)
        {
            printf("
    	关键字		姓名
    ");
            printf("	%d",NAME[i].v);
            printf("	%s",NAME[i].s);
        }
        return ;
    }
    int menu()
    {
        printf("
    
    ");
        printf("                *****汉字姓名拼音哈希表展示查找系统*****
    ");
        printf("                ***1.展示姓名拼音和关键字            ***
    ");
        printf("                ***2.展示哈希表                      ***
    ");
        printf("                ***3.查找关键字                      ***
    ");
        printf("                ***4.退出                            ***
    ");
        printf("                ****************************************
    ");
        printf("
    ");
        return 0;
    }
    int main()
    {
        int i,n;
        int flag;
        flag=1;
        while(1)
        {
            menu();
    
            if(flag==1)
            {
                init();
                creathash();
                flag=0;
            }
            scanf("%d",&n);
            getchar();
            if(n<1||n>4)
            {
                printf("输入有误,请重新输入!!!
    ");
                continue;
            }
            else
            {
                if(n==1)
                {
                    printf("展示所准备的姓名拼音及其所组成的关键字:
    ");
                    display();
                }
                else if(n==2)
                {
                    displayhash();
                }
                else if(n==3)
                {
                    searchhash();
                }
                else if(n==4)
                {
                    return 0;
                }
            }
    
        }
        return 0;
    }

    6 程序调试与测试

    1)打印姓名表:

    2)打印哈希表

    3)查找姓名:

  • 相关阅读:
    【西瓜书】周志华《机器学习》学习笔记与习题探讨(一)
    01-线性回归算法
    NumPy 字符串函数
    Numpy函数分类
    Excel一对多查询(index+small+if)
    支付机构MRC模
    数据分析方法论
    窗口函数/解析函数
    数据分析
    底层逻辑
  • 原文地址:https://www.cnblogs.com/wkfvawl/p/10257026.html
Copyright © 2011-2022 走看看