数据结构设计报告--哈希查找与实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
数据结构课程设计报告书
班级BX1001
专业计算机科学与技术学号101003020139
姓名赵冠博
课题描述:
哈希表的查找与实现分析
1、 需求分析:
本次课程设计需要实现哈希表的建立和查找,具体内容如下:
建立哈希函数,从而根据用户输入的数据元素个数和各元素的值建立哈希表,即数据的添加和存储。
如果输入的元素个数超出规定范围,则打印出错信息,并提示重新输入信息。
哈希表建立好之后,用户可以输入想要查找的值,屏幕显示相应信息。
如果存在此值,屏幕显示该值信息;如果不存在,则显示该值不存在;如果想退出系统,则按提示输入命令。
2、 总体结构设计:
1> 一个哈希表结构hashtable ,
2>一个main ()主函数(完成数据输入和函数调用)、
3>五个功能函数:
Initialhash ()//初始化哈希表
Printhash ()//输出哈希表的所有元素及其位置
Searchhash ()//查找哈希表
inserthash ()//查找哈希表
deletehash ()//查找哈希表
3、 各子模块设计:
构成如下图所示:
【设计思想】
选取某个函数,依该函数按关键字计算元素的存储位置,并按此存放;查找时,由同一个函数对给定值kx 计算地址,将kx 与地址单元中元素关键字进行比较,确定查找是否成功,这就是哈希方法。
哈希方法中使用的转换函数称为Searchhash () Printhash () Initalhash() inserthash () deletehash
哈希查找程序
main()
哈希函数。
程序首先通过插入操作建立哈希表,接着显示数据,然后运用哈希查找找到数据,如没有找到则显示查找错误,找到则显示查找成功。
4、编程实现:
【实验程序主要代码】:
#define MAXSIZE 12 //哈希表的最大容量,与所采用的哈希函数有关enum BOOL{False,True};
enum HAVEORNOT{NULLKEY,HAVEKEY,DELKEY};
//哈希表元素的三种状态,没有记录、有记录、有过记录但已被删除
typedef struct //定义哈希表的结构
{ int elem[MAXSIZE]; //数据元素体
HAVEORNOT elemflag[MAXSIZE];//元素状态,没有记录、有记录、有过记录但已被删除 int count; // 哈希表中当前元素的个数
}HashTable;
typedef struct
{ int keynum; // 记录的数据域,只有关键字一项
}Record;
void InitialHash(HashTable&); // 初始化哈希表
void PrintHash(HashTable); // 显示哈希表中的所有元素
BOOL SearchHash(HashTable,int,int&); // 在哈希表中查找元素
BOOL InsertHash(HashTable&,Record); // 在哈希表中插入元素
BOOL DeleteHash(HashTable&,Record); // 在哈希表中删除元素
int Hash(int); // 哈希函数
void main()
{ HashTable H; // 声明哈希表H
char ch,j='y';
int position,n,k;
Record R;
BOOL temp;
InitialHash(H);
while(j!='n')
{ printf("\n\t 哈希查找 ");
printf("\n\t**************************************");
printf("\n\t* 1-----建表 *");
printf("\n\t* 2-----显示 *");
printf("\n\t* 3-----查找 *");
printf("\n\t* 4-----插入 *");
printf("\n\t* 5-----删除 *");
printf("\n\t* 0-----退出 *");
printf("\n\t**************************************");
printf("\n\n\t请输入菜单号:");
scanf(" %c",&ch); // 输入操作选项
switch(ch)
{ case '1':printf("\n请输入元素个数(<10): ");
scanf("%d",&n);
printf("\n");
for( k=0;k<n;k++)
{ printf("请输入第%3d个整数: ",k+1);
scanf("%d",&R.keynum); // 输入要插入的记录
temp=InsertHash(H,R);
};
break;
case '2':if(H.count) PrintHash(H); // 哈希表不空
else printf("\n散列表为空表!\n");
break;
case '3':if(!H.count) printf("\n散列表为空表!\n"); // 哈希表空
else
{ printf("\n请你输入要查找元素(int) :");
scanf("%d",&R.keynum); // 输入待查记录的关键字
temp=SearchHash(H,R.keynum,position);
// temp=True:记录查找成功;temp=False:没有找到待查记录
if(temp) printf("\n查找成功该元素位置是 %d\n",position); else printf("\n本散列表没有该元素!\n");
}
break;
case '4':if(H.count==MAXSIZE) // 哈希表已满 { printf("\n散列表已经满!\n");
break; }
printf("\n请输入要插入元素(int):");
scanf("%d",&R.keynum); // 输入要插入的记录 temp=InsertHash(H,R);
// temp=True:记录插入成功;temp=False:已存在关键字相同的记录
if(temp) printf("\n元素插入成功!\n");
else printf("\n元素插入失败,相同元素本散列表已经存在!\n"); break;
case '5':printf("\n请你输入要删除元素(int):");
scanf("%d",&R.keynum); // 输入要删除记录的关键字
temp=DeleteHash(H,R);
// temp=True:记录删除成功;temp=False:待删记录不存在
if(temp) printf("\n删除成功!\n");
else printf("\n删除元素不在散列表中!\n");
break;
default: j='n';
}
}
printf("\n\t欢迎再次使用本程序,再见!\n");
}
void InitialHash(HashTable &H) // 哈希表初始化
{ int i;
H.count=0;
for(i=0;i<MAXSIZE;i++) H.elemflag[i]=NULLKEY;
}
void PrintHash(HashTable H) // 显示哈希表所有元素及其所在位置
{ int i;
for(i=0;i<MAXSIZE;i++) printf("%-4d",i); // 显示哈希表中记录所在位置
printf("\n");
for(i=0;i<MAXSIZE;i++) // 显示哈希表中记录值
if(H.elemflag[i]==HAVEKEY) printf("%-4d",H.elem[i]);
else printf("%4c",' ');
printf("\ncount:%d\n",H.count); // 显示哈希表当前记录数
}
BOOL SearchHash(HashTable H,int k,int &p)
{ // 在开放定址哈希表H中查找关键字为k的数据元素,若查找成功,以p指示待查
//数据元素在表中的位置,并返回True;否则,以p指示插入位置,并返回False
int p1;
p1=p=Hash(k); // 求得哈希地址
while(H.elemflag[p]==HAVEKEY&&k!=H.elem[p]) //该位置填有记录并且关键字不相等 { p++; // 冲突处理方法:线性探测再散列
if(p>=MAXSIZE) p=p%MAXSIZE; // 循环搜索
if(p==p1) return False; // 整个表已搜索完,没有找到待查元素 }
if(k==H.elem[p]&&H.elemflag[p]==HAVEKEY) // 查找成功,p指示待查元素位置 return True;
else return False; // 查找不成功
}
BOOL InsertHash(HashTable &H,Record e)
{ // 查找不成功时插入元素e到开放定址哈希表H中,并返回True,否则返回False int p;
if(SearchHash(H,e.keynum,p)) // 表中已有与e有相同关键字的元素
return False;
else
{ H.elemflag[p]=HAVEKEY; // 设置标志为HAVEKEY,表示该位置已有记录
H.elem[p]=e.keynum; // 插入记录
H.count++; // 哈希表当前长度加一
return True;
}
}
BOOL DeleteHash(HashTable &H,Record e)
{ // 在查找成功时删除待删元素e,并返回True,否则返回False
int p;
if(!SearchHash(H,e.keynum,p)) return False; // 表中不存在待删元素
else
{ H.elemflag[p]=DELKEY; // 设置标志为DELKEY,表明该元素已被删除 H.count--; // 哈希表当前长度减一
return True;
}
}
int Hash(int kn)
{ return (kn%11); } // 哈希函数:H(key)=key MOD 11
5、测试结果:
【程序运行结果】建表和显示:查找:
插入:
删除:
通过分析输入数据和运行结果,证明程序顺利完成实验内容和要求。
6、总结:
通过这个星期的课程设计,我的收获还是不少。
我的c语言水平有了比较大的提高,其中c语言关于指针,链表的操作理解的比以前深刻不少。
另外是
数据结构方面的提高,对存储结构,及各种查找排序方面也有不少的提高。
虽
然我做的程序里还有写问题,做的不够深入,但独立完成一个比较大一点的程
序的经历也是很宝贵的。
通过这次做课程设计,使我对数据结构这门课的认识更进一步,这门课确实是学好计算机程序设计的基础。
与此同时,自己对程序设计中应该注意的一
些问题也有了自己的一些想法。
首先,一个程序要达到正确性,可读性,健壮
性,高效率和低存储量的要求,这样用户在使用程序的时候才会更加满意,程
序才能得到更多的关注。
其次,要养成良好的编程习惯,在做一个程序之前,
要对该程序的存储结构,抽象数据类型和应该具备的功能以及各模块之间的调
用关系有一个总体的把握,画出必要的算法流程图或写出必要的伪码来表示各
模块应该具备的功能。
再次,在编写程序的过程中应该对一些难于理解的地方
加上必要的注释,这样会使在之后的调试与维护阶段更加容易,在定义功能函
数与变量时应该尽量采取有表征意义的名称,这样也可达到见名知意的效果。
最后,在程序的调试阶段,应该针对程序中用户可能进行的错误操作给出解决
的方法,要尽量选出几组具有毁灭性的数据来进行测试,在程序不能正常处理
的情况下要采取一些方案使这样的问题得以解决。
做程序是一个比较累的工
作,特别是当遇到困难时,程序通不过时,真的很令人沮丧。
但是改正一个错
误时,那种喜悦心情也很令人期盼,这种心情堪比久旱见甘霖的喜悦。
就是因
为有这种令人身心愉悦的可能,我才得以能够整晚不睡来改程序中的不足之
处。
编程中有苦有乐,其中的苦乐只有亲身经历才能体会到。
要想做出好的程
序,必须做好忍受其间痛苦的准备。
7、参考文献。
[1] 严蔚敏,吴伟民.《数据结构》,清华大学出版社,2001年1月
[2] 刘怀亮.《数据结构习题解析与实验指导》,冶金工业出版社,2005
年2月
[3] 谭浩强.《数据结构》,清华大学出版社,1999年12月。