哈希表实验报告

时间:2024.5.13

 


数据结构》课程设计报告

哈希表问题

    :

              : 信息管理与信息系统

    :  083221

    :  08322126

指导老师 :  刘自强

设计时间20##57


一,摘-----------------------------------------------------------------------1

二,设计要求与分析

2.1  课程设计要求-------------------------------------------------------2

2.2  程序分析-------------------------------------------------------------2

三,数据结构选择与概要设计

3.1  数据结构选择-------------------------------------------------------3

3.2  Hash函数流程图---------------------------------------------------4~9

四,设计算法

4.1  建立节点-------------------------------------------------------------10

4.2  哈希函数的定义----------------------------------------------------10

4.3  哈希查找-------------------------------------------------------------11

4.4  程序测试-------------------------------------------------------------11

五,使用说明与测试结果

     5.1  使用说明-------------------------------------------------------------11

     5.2  主菜单截图----------------------------------------------------------12

     5.3  添加记录截图-------------------------------------------------------12

     5.4  查找截图-------------------------------------------------------------13

     5.5  散列结果截图-------------------------------------------------------13

     5.6  清空记录截图-------------------------------------------------------14

六,程序源代码及实验心得

     6.1  源代码----------------------------------------------------------------14~18

     6.2  实验心得-------------------------------------------------------------19

     课程设计评分表-----------------------------------------------------------20


 

本设计主要要求分别以电话号码和用户名为关键字建立哈希表,并实现查找功能。所以本设计的核心问题是如何解决散列的问题,由于结点的个数无法确认,并且如果采用线性探测法散列算法,删除结点会引起“信息丢失”的问题。所以采用链地址法散列算法。采用链地址法,当出现同义词冲突时,使用链表结构把同义词链接在一起。

首先,解决的是定义链表结点,在链接地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成.name[8] 、num[11]和address[20]都是char浮点型采用链地址法,其中的所有同义词构成一个单链表,再由一个表头结点指向这个单链表的第一个结点。这些表头结点组成一个一维数组,即哈希表。


二,设计要求与分析

2.1         课程设计要求

设计哈希表实现电话号码查询系统。设计程序完成以下要求:

(1)设每个记录有下列数据项:电话号码、用户名、地址;

(2)从键盘输入各记录,分别以电话号码和用户名为关键字建立哈希表;

(3)采用再哈希法解决冲突;

(4)查找并显示给定电话号码的记录;

(5)查找并显示给定用户的记录。

2.2  程序分析

具体思路为:

(1)对于以号码为关键字的散列函数,是将十一个数字全部相加,然后对20求余。得到的数作为地址。对于以用户名为关键字的散列函数,是将所有字母的ASCLL码值相加,然后对20求余。

(2)要添加用户信息,即要有实现添加结点的功能的函数,所以要设计一个必须包括一个输入结点信息、添加结点的函数;

(3)要实现查找函数,则必须包括一个查找结点的函数;

另外还有一个必不可少的就是运行之后要有一个主菜单,即要设计一个主函数(main())。

(4)测试数据的选择最后,程序完成后要对程序进行编译调试,执行后要选择数据进行测试,这里选择的测试数据为:

1.姓名:郑健;电话:1234567;地址:江西九江;

2.姓名:吴任;电话:2345678;地址:江西南昌;

3.姓名:黄鑫;电话:3456789;地址:江西上饶;

三,数据结构选择与概要设计

3.1        数据结构选择

本设计涉及到的数据结构为:哈希表。要求输入电话号码、用户名、地址三个信息,并要求分别以电话号码和用户名为关键字进行查找,所以本问题要用到两个哈希函数,进行哈希查找。

在链地址法中,每个结点对应一个链表结点,它由三个域组成,而由于该程序需要分别用电话号码和用户名为关键字建立哈希表,所以该链表结点它是由四个域组成,链接地址法结点结构如图:

其中name[8]和num[11]是分别为以电话号码和用户名为关键字域,存放关键字(key);address[20](data)为结点的数据域,用来存储用户的地址。Next指针是用来指向下一个结点的地址。


3.2        Hash函数流程图

以号码为关键字的hash函数流程图

    

   

     


以姓名为关键字的hash函数流程图


 添加信息节点流程图

 

姓名查找流程图



号码查询流程图


四,设计算法

4.1        建立节点

     struct node

{

char name[8],address[20];

char num[11];

node * next;

};

typedef node* pnode; //可以为一个已有的数据类型声明多个别名,这里为该类型声明了两个指针

typedef node* mingzi;

node **phone;

node **nam;

node *a;

4.2  哈希函数的定义

本程序要设计两个hash()函数,分别对应电话号码和用户名。对关键字进行模运算,将运算结果所得的余数作为关键字(或结点)的存储地址,方法如下:以电话号码为关键字建立哈希函数hash(char num[11])。以用户名为关键字建立哈希函数hash2(char name[8])。利用强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除以20后的余数。将计算出来的数作为该结点的地址赋给key2。

void hash(char num[11]); //以电话号码为关键字建立哈希函数

//哈希函数的主旨是将电话号码的十一位数字全部加起来

{

int i = 3;

key=(int)num[2];

while(num[i]!=NULL)

{

key+=(int)num[i];

i++;

}

key=key%20; } //利用强制类型转换,将用户名的每一个字母的ASCLL码值相加并且除以20后的余数         

void hash2(char name[8]); //哈希函数 以用户名为关键字建立哈希函数

{

int i = 1;

key2=(int)name[0];

while(name[i]!=NULL)

{

key2+=(int)name[i];

i++;

}

key2=key2%20;

}

4.3   哈希查找

想要实现查找功能,同样需要两个查找函数,无论以用户名还是以电话号码为关键字,首先,都需要利用hash函数来计算出地址。再通过比对,如果是以电话号码为关键字,比较其电话号码是否相同,如果相同则输出该结点的所有信息,如果以用户名为关键字,则比较用户名是否相同,如果相同则输出该结点的所有信息。如果找不到与之对应相同的,则输出“无此记录”。

void find(char num[11]) ; //在以电话号码为关键字的哈希表中查找用户信息

{

hash(num);

node *q=phone[key]->next;

while(q!= NULL)

{

if(strcmp(num,q->num)==0)

break;

q=q->next;

}

if(q)

       printf("%s_%s_%s\n",q->name,q->address,q->num);

else printf("无此记录\n");

}

void find2(char name[8]) ;// 在以用户名为关键字的哈希表中查找用户信息

{

hash2(name);

node *q=nam[key2]->next;

while(q!= NULL)

{

if(strcmp(name,q->name)==0)

break;

q=q->next;

}

4.4  程序测试

首先键入0,添加结点信息,然后按1进行查找,分别进行号码和姓名查找,最后可在主菜中,

选择号码散列和姓名散列,由此查看程序运行结果。

至此,就解决了哈希表的设计与实现算法可能出现的各种问题,那么根据以上思路以及对问题的分析和对出现情况的解决则可以写出源程序。

五,使用说明与测试结果

5.1  使用说明

由于address[20]、name[8]和num[11]可以看出地址可输入的最大字符数是20,姓名可输入的最大字符数是8,电话号码都为11位。

5.2        主菜单截图

5.3        添加记录截图

5.4        查找截图

5.5        散列结果截图

5.6        清空记录截图

六,程序源代码及实验心得

6.1        源代码

#include<stdio.h>

#include<string.h>

#define NULL 0

unsigned int key;

unsigned int key2;

int *p;

struct node

{

char name[8],address[20];

char num[11];

node * next;

};

typedef node* pnode;

typedef node* mingzi;

node **phone;

node **nam;

node *a;

void hash(char num[11])

   {

int i = 3;

key=(int)num[2];

while(num[i]!=NULL)

{

key+=(int)num[i];

i++;

}

key=key%20;

}

void hash2(char name[8])

{

int i = 1;

key2=(int)name[0];

while(name[i]!=NULL)

{

key2+=(int)name[i];

i++;

}

key2=key2%20;

}

node* input()

{

node *temp;

temp = new node; 

temp->next=NULL;

printf("请输入姓名:\n");

scanf("%s",temp->name);

printf("输入地址: \n");

scanf("%s",temp->address);

printf("输入电话:\n");

scanf("%s",temp->num);

  return temp;

}

int apend() 

{

node *newphone;

node *newname;

newphone=input();

newname=newphone;

newphone->next=NULL;

newname->next=NULL;

hash(newphone->num);  

hash2(newname->name);

newphone->next = phone[key]->next;

phone[key]->next=newphone;

newname->next = nam[key2]->next; 

nam[key2]->next=newname;

return 0;

}

void create() 

{

int i;

phone=new pnode[20];

for(i=0;i<20;i++)

{

phone[i]=new node;

phone[i]->next=NULL;

}

}

void create2()

{

int i;

nam=new mingzi[20];

for(i=0;i<20;i++)

{

nam[i]=new node;

nam[i]->next=NULL;

}

}

void list() 

{

int i;

node *p;

for(i=0;i<20;i++)

{

p=phone[i]->next;

while(p)

{

       printf("%s_%s_%s\n",p->name,p->address,p->num);

p=p->next;

}

}

}

void list2() 

{

int i;

node *p;

for(i=0;i<20;i++)

{

p=nam[i]->next;

while(p)

{

       printf("%s_%s_%s\n",p->name,p->address,p->num);

p=p->next;

}

}

}

void find(char num[11]) 

{

hash(num);

node *q=phone[key]->next;

while(q!= NULL)

{

if(strcmp(num,q->num)==0)

break;

q=q->next;

}

if(q)

printf("%s_%s_%s\n",q->name,q->address,q->num);

else printf("无此记录\n");

}

void find2(char name[8])

{

hash2(name);

node *q=nam[key2]->next;

while(q!= NULL)

{

if(strcmp(name,q->name)==0)

break;

q=q->next;

}

if(q)

printf("%s_%s_%s\n",q->name,q->address,q->num);

else printf("无此记录\n");

}

void menu() //菜单

{

printf("0.添加记录\n");

printf("1.查找记录\n");

printf("2.姓名散列\n");

printf("3.号码散列\n");

printf("4.清空记录\n");

printf("5.退出系统\n");

}

int main()

{

char num[11];

char name[8];

create();

create2() ;

int sel;

while(1)

{

menu();

scanf("%d",&sel);

if(sel==1)

{

       printf("6号码查询,7姓名查询\n");

int b;

scanf("%d",&b);

if(b==6)

{

       printf("请输入电话号码:\n");

       scanf("%s",num);

       printf("输出查找的信息:\n");

       find(num);

}

else

{

       printf("请输入姓名:\n");

       scanf("%s",name);

       printf("输出查找的信息:\n");

find2(name);}}

if(sel==2)

{printf("姓名散列结果:\n");

list2();}

if(sel==0)

{printf("请输入要添加的内容:\n");

apend();}

if(sel==3)

{printf("号码散列结果:\n");

list();

}

if(sel==4)

 printf("列表已清空:\n");

create();create2();}

if(sel==6) return 0;

}

return 0;

}

6.2  实验心得

     一周的课程设计今天结束了。很快,收获很多。感觉像是一个从无到有的过程,非常的充实。我做的课题是“哈希表问题”。基本算法老师在课堂上有涉及过,但具体的还要靠自己去钻研。我在一边做上机实验时,一边到图书馆查阅书籍,反复实践操作,往往比书本上得到的更多,体会也更深刻。通过本次课程设计对哈希表问题有了一个比较全面的认识和了解。

     哈希表问题,在存储位置和关键字之间建立对应关系f,根据对应关系f找到定值K。若结构中存在关键字和定值K相等的记录,必定在f(K)的存储位置上,由此可以省去比较过程,直接找到所查记录。哈希表其实不难,课程设计考验的是我们的学习态度,独立思考问题,和解决问题的能力。把握这次机会肯定大有收获。


东华理工学院长江学院

课程设计评分表

学生姓名:  郑 健     班级:083221       学号:08322126

课程设计题目:哈希表问题

更多相关推荐:
实验5 哈希表实验报告

哈希表一实验目的学会哈希函数的构造方法处理冲突的机制以及哈希表的查找二实验内容说明以下概念1哈希函数在一般情况下需在关键字与记录在表中的存储位置之间建立一个函数关系以fkey作为关键字为key的记录在表中的位置...

哈希表实验报告

1实验目的掌握HASH表的建立和查表技术2实验内容1编写函数实现线性探查HASH表的插入和查找算法2编写主函数完成以下功能3定义一个长度为128的HASH表4随机产生120个0255之间的不重复的伪随机整数依次...

哈希表(实验报告附C++源码)

散列表一问题描述我们希望在浩瀚的图书中去发现一本书是否存在我们不知道书的编号只知道它的书名其实这已经不错了通过书名来查询它是否存在为了简化问题我们假设每本书的书名都是一组小写字母组成长度不超过100字符二需求分...

数据结构课程设计--哈希表实验报告

福建工程学院课程设计课程算法与数据结构题目哈希表专业网络工程班级xxxxxx班座号xxxxxxxxxxxx姓名xxxxxxx20xx年12月31日实验题目哈希表一要解决的问题针对同班同学信息设计一个通讯录学生信...

哈希表实验报告

数据结构实验报告四哈希表查找名字字符串实验题目哈希表查找名字字符串实验目标输入一组名字至少50个将其保存并利用哈希表查找输出哈希查找冲突次数哈希表负载因子查找命中率数据结构哈希表和数组二维二维数组用于静态顺序存...

哈希表实验报告完整版

实验报告姓名学号1实验题目针对某个集体中人名设计一个哈希表使得平均查找长度不超过R并完成相应的建表和查表程序基本要求假设人名为中国人姓名的汉语拼音形式待填入哈希表的人名共有30个取平均查找长度的上限为2哈希函数...

哈希表实验报告 定稿

数据结构课程设计报告设计题目哈希表的设计与实现专业通信工程班级学生学号指导教师起止时间XXXXXX学院年学期目录一设计要求1二数据结构选择与概要设计21数据结构选择122流程图2以号码为关键字哈希流程2以姓名为...

哈希表实验报告

数据结构课程设计报告哈希表设计姓名学号院系班级二一三年七月一需求分析1实验内容和实验目的1针对某个集体中的人名设计一个哈希表使得平均查找长度不超过R完成相应的建立和查表程序2人名为汉语拼音形式最长不超过19个字...

多表查询实验报告

数据库系统概论实验报告实验名称实验人实验地点实验日期多表查询一实验准备1硬件及软件环境要求为了使该实验顺利进行需要有一台计算机计算机必须安装Windows20xxWindowsXP或WindowsNT操作系统还...

北京理工大学 实验二 实验报告表

实验二实验报告表实验名称计算机中的数据表示与计算学号20xx216886姓名实验报告表21数值型数据在计算机中的二进制实验记录表唐玮班级计算机154班实验时间20xx年说明本实验对计算机内存数据的存放拟定为整数...

实验十五 实验报告表

五实验报告学号姓名班级实验时间年月日实验报告用计算机解题算法一请画出实验内容1真假话问题计算机求解算法的流程图二假定一个数列中有n个杂乱无章的整数请你用流程图描述一下插入排序的算法1

实验六 实验报告表

实验六实验报告表实验报告表61打开文件过程演示实验记录表实验报告表62创建文件过程演示实验记录表实验报告表63删除文件过程实验记录表

哈希表实验报告(10篇)