当前位置:文档之家› 哈希表查找的设计

哈希表查找的设计

哈希表查找的设计一.问题描述:哈希表查找的设计:设哈希表长为20,用除留余数法构造一个哈希函数,以开放定址法中的线性探测再散列法作为解决冲突的方法,编程实现哈希表查找、插入和建立算法。

二.需求分析:程序可实现用户与计算机的交互过程。

在计算机显示提示信息后,可由用户键入运算命令以实现对应的功能,包含数据的录入、查找、删除、显示等功能。

本程序旨在实现哈希函数的构造与处理存储冲突,因而指定哈希表存储的数据类型为简单的整型数字,在实用性上还有所欠缺。

但根据用户需求的变化,可以对程序的基本数据类型进行改造,以实现更为丰富的功能,进而体现哈希表在查找数据时的优越性。

三.算法思想:在设定哈希表的抽象数据类型时,要有查找数据元素的操作。

另外,插入操作和删除操作也要用到查找数据元素操作,以查看该数据元素是否存在,因此可以设计查找元素操作包括插入和删除操作的查找。

因此,查找操作就有两种情况:一种情况是插入操作时寻找空闲单元的查找;另一种情况是在查找和删除操作时寻找该元素是否在哈希表中已存在的查找。

插入操作时寻找空闲单元查找的特征是哈希表中不存在该对象,设计此时查找函数返回该空闲单元位置的“正”值;查找和删除操作时寻找该元素是否在哈希表中已存在的特征是哈希表中已存在该数据元素,设计此时查找函数返回该数据单元位置的“负”值。

进而执行后续操作。

为了区分哈希表中每一个表元素的当前状态,为每一个表元素设置一个“标志”定为tag。

tag=0表示该元素为空;tag=1表示该元素以存放有数据元素;tag=-1表示该元素中存放的数据元素已被删除。

判断当tag为0或-1时都可以进行插入操作。

四.概要设计:1. 哈希表抽象数据类型的定义:ADT HashT able{数据对象:D={ai|ai∈ElemSet, i=1,2,...n, n≥0}数据关系:R1={<ai-1,ai>|ai-1∈D, i=1,2,...n}基本操作:Initiate( &h )操作结果:构造一个空的哈希表h。

SearchHash( h, x, p )初始条件:哈希表h已存在;p为除留余数法中除数,由用户指定。

操作结果:查找表中元素与指定数据x比较。

元素已存在时返回其所在位置的负数下标、不存在时返回其位置的正数下标、遍历哈希表后未查找到时返回表长。

Insert( &h, x, p )初始条件:哈希表h已存在。

操作结果:查找操作后插入元素x至哈希表。

若元素已存在或哈希表已满时插入操作失败,返回值为0。

Delete(&h, x, p )初始条件:哈希表h已存在。

操作结果:查找操作后从哈希表中删除元素x。

若元素不在表中时删除操作失败,返回值为0。

Print( h )初始条件:哈希表h已存在。

操作结果:显示哈希表中元素及存储状态。

Clear( &h )初始条件:哈希表h已存在。

操作结果:清空哈希表。

}ADT HashT able2. 程序模块:Hash.h——头文件,包含哈希表抽象数据类型。

Hash.cpp——主程序,为哈希表操作面板。

五.程序代码:——————Hash.h文件——————#include<malloc.h>#include<iostream.h>#include<iomanip.h>#include<process.h>#include<ctype.h>#define T ableSize 20 //哈希表长20#define SUCCESS 1#define UNSUCCESS 0typedef int Status;typedef struct{//定义元素关键字类型int key;}Elemtype;typedef struct{//定义哈希表中基本单元,包含数据与标志两部分Elemtype elem; //数据部分,存放关键字int tag; //标志部分,tag=0表示表单元为空,//tag=1表示表单元已存放数据元素,//tag=-1表示表单元中存放的数据已被删除}HashItem;typedef struct{//定义哈希表,包含表单元数组与当前存储量HashItem table[T ableSize];int currentSize; //当前哈希表存储量}HashT able;Status Initiate(HashT able *h){//初始化操作int i;for(i=0; i<T ableSize; i++){(*h).table[i].tag=0; //tag标志置为0(*h).table[i].elem.key=NULL; //空单元默认值设为NULL}(*h).currentSize=0;return SUCCESS;}int SearchHash(HashT able h, Elemtype x, int p){//查找元素操作int i=x.key%p; //除留余数法定哈希地址,主程序中定义一不大于表长的素数pint j=i;while(h.table[j].tag==1 && h.table[j].elem.key!=x.key){//冲突时j=(j+1)%T ableSize; //开放定址法,线性探测再散列,求出新位置jif(j==i){cout<<"哈希表中未查找到"<<x.key<<endl;return T ableSize; //全表遍历后未搜索到所给元素,返回表长}}if(h.table[j].tag==1) //元素已存在时返回其位置的负数下标{cout<<"该元素在哈希表的第"<<j<<"位"<<endl; return -j;}else //元素不存在时返回其位置的下标{cout<<"哈希表中未查找到"<<x.key<<endl; return j;}}Status Insert(HashT able *h, Elemtype x, int p){//插入元素操作int i=SearchHash(*h, x, p); //先调用查找操作if(i<0) //元素已存在时,插入失败{cout<<x.key<<"元素已存在,无法再录入,操作失败!"<<endl<<endl;return UNSUCCESS;}else{if(i!=T ableSize && (*h).table[i].tag!=1) //哈希表有剩余空间时,进行插入操作{(*h).table[i].elem.key=x.key; //插入元素(*h).table[i].tag=1; //tag标志置为1(*h).currentSize++; //表存储量加1cout<<"录入成功!"<<endl<<endl;return SUCCESS;}elseif(i==T ableSize) //哈希表已满时,插入失败{cout<<"哈希表已满,无法再插入"<<x.key<<",操作失败!"<<endl<<endl;return UNSUCCESS;}}}Status Delete(HashT able *h, Elemtype x, int p){//删除元素操作int i=SearchHash(*h, x, p); //先调用查找操作if(i<=0) //查找成功,元素存在时,进行删除操作{(*h).table[-i].elem.key=NULL; //单元值设为NULL(*h).table[-i].tag=-1; //tag标志置为-1(*h).currentSize--; //表存储量减1cout<<"删除成功!"<<endl;return SUCCESS;}elsecout<<"删除失败!"<<endl;return UNSUCCESS;}Status Print(HashT able h){//打印表操作cout<<endl<<"哈希表序数存储情况存储元素"<<endl;for(int i=0;i<T ableSize;i++){cout<<setw(4)<<i<<setw(10)<<h.table[i].tag<<setw(10)<<h.table[i].elem.key<<endl;} cout<<endl<<"表中非空元素个数:"<<h.currentSize<<endl<<endl;return SUCCESS;}Status Clear(HashT able *h){//置空表操作for(int i=0;i<T ableSize;i++){(*h).table[i].tag=0; (*h).table[i].elem.key=NULL;}(*h).currentSize=NULL;cout<<"哈希表已全部置空!"<<endl;return SUCCESS;}——————Hash.cpp文件——————int main( ){cout<<endl<<"******** HashT able T est File********"<<endl<<endl;HashT able h;Initiate(&h);int prime;cout<<"请输入一个小于20的质数:";cin>>prime;char choice;while(1){cout<<"————————————————————————"<<endl;cout<<"按a 输出哈希表"<<endl;cout<<"按b 查找指定元素在表中的位置"<<endl;cout<<"按c 录入元素"<<endl;cout<<"按d 删除元素"<<endl;cout<<"按e 清空哈希表"<<endl;cout<<"按其他键退出"<<endl<<endl<<"请选择:";cin>>choice;cout<<"————————————————————————"<<endl;switch(choice){case'a':{ Print(h); break;}case'b':{ cout<<"请输入需要查找的元素的值:";Elemtype a;cin>>a.key;SearchHash(h,a,prime);break;}case'c':{ cout<<"请输入需要输入的元素个数(1~20):";int n,i;cin>>n;Elemtype *pi=0;pi=(Elemtype*)malloc(n*sizeof(Elemtype));cout<<"请依次输入"<<n<<"个元素的值:"<<endl;for(i=0;i<n;i++){ cin>>pi[i].key; Insert(&h,pi[i],prime);}break;}case'd':{ cout<<"请输入需要删除的元素的值:";Elemtype c;cin>>c.key;Delete(&h,c,prime);break;}case'e':{ Clear(&h); break; }default:{return 0;}}}}六.运行结果:程序运行,先按要求输入一小于20的质数作为除留余数法的除数因子。

相关主题