数据结构设计报告--哈希查找与实现

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 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月。

相关文档
最新文档