数据结构实验四哈希表及其查找

合集下载

哈希表(Hash)的查找

哈希表(Hash)的查找

哈希表(Hash)的查找一、哈希表相关概念1、哈希函数的基本概念哈希表又称散列表。

哈希表存储的基本思想是:以数据表中的每个记录的关键字 k为自变量,通过一种函数H(k)计算出函数值。

把这个值解释为一块连续存储空间(即数组空间)的单元地址(即下标),将该记录存储到这个单元中。

在此称该函数H为哈希函数或散列函数。

按这种方法建立的表称为哈希表或散列表。

理想情况下,哈希函数在关键字和地址之间建立了一个一一对应关系,从而使得查找只需一次计算即可完成。

由于关键字值的某种随机性,使得这种一一对应关系难以发现或构造。

因而可能会出现不同的关键字对应一个存储地址。

即k1≠k2,但H(k1)=H(k2),这种现象称为冲突。

把这种具有不同关键字值而具有相同哈希地址的对象称“同义词”。

在大多数情况下,冲突是不能完全避免的。

这是因为所有可能的关键字的集合可能比较大,而对应的地址数则可能比较少。

对于哈希技术,主要研究两个问题:(1)如何设计哈希函数以使冲突尽可能少地发生。

(2)发生冲突后如何解决。

2、哈希函数的构造方法常见的构造方法有很多种,如直接定址法,数字分析法,平方取中法等。

接下来,我们介绍其中的几种:(1)除留余数法取关键字k被某个不大于表长m的数p除后所得余数作为哈希函数地址的方法。

即:H(k)=k mod p这种方法的关键是选择好p。

使得数据集合中的每一个关键字通过该函数转化后映射到哈希表的任意地址上的概率相等。

理论研究表明,一般取p为小于m的最大质数或不包含小于20的质因素的合数。

(2)平方取中法先将关键字平方,然后取其中间几位作为散列地址。

所取位数由地址空间范围决定。

若地址空间小于所取位数值决定的范围,可通过乘以一比例因子来解决。

(3)折叠法把关键字分割成位数相等(最后一部分的位数可以不同)的几部分,然后通过折叠后将几部分进行相加,丢掉进位位,所得值即为散列地址。

散列的位数由地址空间的位数而定。

分割方法:从右至左相加方法有两种:移位叠加:将分割后的各部分低位对齐相加。

详解哈希表的查找

详解哈希表的查找

详解哈希表的查找哈希表和哈希函数在记录的存储位置和它的关键字之间是建立一个确定的对应关系(映射函数),使每个关键字和一个存储位置能唯一对应。

这个映射函数称为哈希函数,根据这个原则建立的表称为哈希表(Hash Table),也叫散列表。

以上描述,如果通过数学形式来描述就是:若查找关键字为key,则其值存放在f(key) 的存储位置上。

由此,不需比较便可直接取得所查记录。

注:哈希查找与线性表查找和树表查找最大的区别在于,不用数值比较。

冲突若key1 ≠ key2 ,而f(key1) = f(key2),这种情况称为冲突(Collision)。

根据哈希函数f(key)和处理冲突的方法将一组关键字映射到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“像”作为记录在表中的存储位置,这一映射过程称为构造哈希表。

构造哈希表这个场景就像汽车找停车位,如果车位被人占了,只能找空的地方停。

构造哈希表由以上内容可知,哈希查找本身其实不费吹灰之力,问题的关键在于如何构造哈希表和处理冲突。

常见的构造哈希表的方法有 5 种:(1)直接定址法说白了,就是小学时学过的一元一次方程。

即 f(key) = a * key + b。

其中,a和b 是常数。

(2)数字分析法假设关键字是R进制数(如十进制)。

并且哈希表中可能出现的关键字都是事先知道的,则可选取关键字的若干数位组成哈希地址。

选取的原则是使得到的哈希地址尽量避免冲突,即所选数位上的数字尽可能是随机的。

(3)平方取中法取关键字平方后的中间几位为哈希地址。

通常在选定哈希函数时不一定能知道关键字的全部情况,仅取其中的几位为地址不一定合适;而一个数平方后的中间几位数和数的每一位都相关,由此得到的哈希地址随机性更大。

取的位数由表长决定。

(4)除留余数法取关键字被某个不大于哈希表表长 m 的数 p 除后所得的余数为哈希地址。

即f(key) = key % p (p ≤ m)这是一种最简单、最常用的方法,它不仅可以对关键字直接取模,也可在折叠、平方取中等运算之后取模。

哈希表的定义查找及分析bklt

哈希表的定义查找及分析bklt
常用的构造哈希(散列)函数的方法
一、直接地址法

取关键字或关键字的某个线性函值为哈希地址
即: H(key) = key 或: H(key) = a* key + b
其中,a, b为常数。
二、数字分析法
假设关键字集合中的每个关键字都是由 s 位 数字组成 (u1, u2, …, us),分析关键字集中的全 体, 并从中提取分布均匀的若干位或它们的组 合作为地址。
查找不成功时的ASL
ASLunsucc=( )/11
= /11
10
11
3
8
线性探测再散列的优点:
只要哈希表未满,总能找到一个空地址。
缺点:会产生二次聚集。
01…
70 19 33 18
5678 9
… 12
9
二、 链地址法
在哈希表的每一个单元中存放一个指针,将所 有的同义词连成一个链表。 假设哈希地址在区间[0 .. m-1]上,则哈希表为
一个指针数组。
typedef struct node{ //定义链表中结点 KeyType key; 其它成员 ; struct node *next;
} Node,*Nodeptr; typedef Nodeptr chainhash[m];// 定义指针数组10
例1: 关键字集合 { 19, 01, 23, 14, 55, 68, 11, 82, 36 }
若采用线性探测再散列处理冲突
0 1 2 3 4 5 6 7 8 9 10
55 01 23 14 68 11 82 36 19
11 21 3 62 5 1
若采用二次探测再散列处理冲突
0 1 2 3 4 5 6 7 8 9 10

哈希实验报告

哈希实验报告

引言概述:本文旨在对哈希实验进行报告,重点介绍哈希实验的二次探测法、哈希函数、哈希表的查找、插入与删除操作,并分析实验结果。

通过本实验的开展,我们对哈希算法的原理、实现和性能有了更深入的理解,也增加了对数据结构的实践能力。

正文内容:一、二次探测法1.定义与原理2.步骤与流程3.优缺点分析4.实验过程与结果5.实验中的注意事项二、哈希函数1.哈希函数的设计原则2.常见的哈希函数算法3.哈希冲突与解决方法4.哈希函数的优化策略5.实验中的哈希函数选择与应用三、哈希表的查找操作1.哈希表的存储结构与基本操作2.直接定址法查找3.拉链法查找4.其他查找方法与比较5.实验结果与分析四、哈希表的插入与删除操作1.插入操作的实现思路2.插入操作的效率分析3.删除操作的实现思路4.删除操作的效率分析5.实验结果分析与对比五、实验结果与总结1.实验数据的统计与分析2.实验中的问题与解决方案3.实验结论与总结4.对哈希算法的进一步探讨与应用展望5.实验的意义与启示总结:通过对哈希实验的详细阐述,我们对二次探测法、哈希函数、哈希表的查找、插入与删除操作有了更深入的了解。

实验结果与分析表明,在哈希表的实现中,选择合适的哈希函数、解决哈希冲突以及优化插入与删除操作,对提高哈希表的性能至关重要。

哈希算法作为一种重要的数据结构应用,具有广泛的应用前景,在实际问题中具有重要的实践意义。

通过本次实验,我们不仅提升了对数据结构的理论理解,也增强了数据结构算法的实践能力,为今后的学习与研究打下了坚实的基础。

数据结构哈希表的实验报告

数据结构哈希表的实验报告

课程实习报告一、需求分析:1.本程序来自于图书馆靠书名来检索想要查找的书问题。

2.本程序要求:(1)根据输入建立图书名称表,采用创建散列表实现。

(2)建散列表后,如果想要查找的数据在散列表中输出yes否则输出no。

二、哈希表简介结构中存在关键字和K相等的记录,则必定存储在f(K)的位置上。

由此,不需比较便可直接取得所查记录。

这个对应关系f称为散列函数(Hash function),按这个思想建立的表为散列表。

* 对不同的关键字可能得到同一散列地址,即key1≠key2,而f(key1)=f(key2),这种现象称冲突。

具有相同函数值的关键字对该散列函数来说称做同义词。

* 综上所述,根据散列函数H(key)和处理冲突的方法将一组关键字映象到一个有限的连续的地址集(区间)上,并以关键字在地址集中的“象”,作为这条记录在表中的存储位置,这种表便称为散列表,这一映象过程称为散列造表或散列,所得的存储位置称散列地址。

这个现象也叫散列桶,在散列桶中,只能通过顺序的方式来查找,一般只需要查找三次就可以找到。

科学家计算过,当负载因子(load factor)不超过75%,查找效率最高。

* 若对于关键字集合中的任一个关键字,经散列函数映象到地址集合中任何一个地址的概率是相等的,则称此类散列函数为均匀散列函数(Uniform Hash function),这就是使关键字经过散列函数得到一个“随机的地址”,从而减少冲突。

程序设计流程程序思想(一)哈希函数unsigned int hash_BKDE(char *str)生成映射地址,成为散列表的编号。

(二)哈希表HashTable::HashTable()通过数组储存元素(三)插入函数void HashTable::insert(char*c)插入字符串,先计算要插入字符串生成的映射地址,然后在相应的地址插入,如果没有空位查找空位插入。

(四)查找函数bool HashTable::find(char*c)进行查找,先计算要生成字符串的地址,再到散列表中进行查找比较。

数据结构查找算法实验报告

数据结构查找算法实验报告

数据结构实验报告实验第四章:实验:简单查找算法一.需求与规格说明:查找算法这里主要使用了顺序查找,折半查找,二叉排序树查找与哈希表查找四种方法。

由于自己能力有限,本想实现其她算法,但没有实现.其中顺序查找相对比较简单,折半查找参考了书上得算法,二叉排序树查找由于有之前做二叉树得经验,因此实现得较为顺利,哈希表感觉做得并不成功,感觉还就是应该可以进一步完善,应该说还有很大得改进余地。

二.设计思想:开始得时候提示输入一组数据。

并存入一维数组中,接下来调用一系列查找算法对其进行处理。

顺序查找只就是从头到尾进行遍历。

二分查找则就是先对数据进行排序,然后利用三个标志,分别指向最大,中间与最小数据,接下来根据待查找数据与中间数据得比较不断移动标志,直至找到。

二叉排序树则就是先构造,构造部分花费最多得精力,比根节点数据大得结点放入根节点得右子树,比根节点数据小得放入根节点得左子树,其实完全可以利用递归实现,这里使用得循环来实现得,感觉这里可以尝试用递归.当二叉树建好后,中序遍历序列即为由小到大得有序序列,查找次数不会超过二叉树得深度。

这里还使用了广义表输出二叉树,以使得更直观。

哈希表则就是利用给定得函数式建立索引,方便查找.三.设计表示:四.实现注释:其实查找排序这部分与前面得一些知识联系得比较紧密,例如顺序表得建立与实现,顺序表节点得排序,二叉树得生成与遍历,这里主要就是中序遍历.应该说有些知识点较为熟悉,但在实现得时候并不就是那么顺利。

在查找到数据得时候要想办法输出查找过程得相关信息,并统计。

这里顺序查找与折半查找均使用了数组存储得顺序表,而二叉树则就是采用了链表存储得树形结构。

为了直观起见,在用户输入了数据后,分别输出已经生成得数组与树。

折半查找由于只能查找有序表,因此在查找前先调用函数对数据进行了排序。

在查找后对查找数据进行了统计.二叉排序树应该说由于有了之前二叉树得基础,并没有费太大力气,主要就是在构造二叉树得时候,要对新加入得节点数据与跟数据进行比较,如果比根节点数据大则放在右子树里,如果比根节点数据小则放入左子树。

哈希表实验报告

哈希表实验报告

数据结构实验报告四——哈希表查找名字(字符串)实验题目:哈希表查找名字(字符串)实验目标:输入一组名字(至少50个),将其保存并利用哈希表查找。

输出哈希查找冲突次数,哈希表负载因子、查找命中率。

数据结构:哈希表和数组(二维)。

二维数组用于静态顺序存储名字(字符串),哈希表采用开放定址法,用于存储名字(字符串)对应的关键字并实现对名字(字符串)的查找。

需要的操作有:1.关键字求取(主函数中两次出现,未单独编为函数)关键字key=abs(字符串首位ASCII码值-第二位ASCII码值+第([]+1)位ASCII码值-最后一位ASCII码值-倒数第二位ASCII码值)*字符串长度(abs为求整数绝对值的函数)。

2.处理关键字的哈希函数(Hash)利用平方取中法求关键值key在哈希表中的位置。

公式add=(key*key)%1000/LENGTH(add 为key在哈希表中的地址)。

int Hash(int key){return((key*key)/1000%LENGTH);}3.处理哈希表中冲突的函数(Collision)利用线性探测再散列处理冲突,利用全局变量count统计冲突次数。

int Collision(int key,int Hashtable[]){int i;for(i=1;i<=LENGTH;i++){if(Hashtable[(Hash(key)+i)%LENGTH]==-1)return((Hash(key)+i)%LENGTH);count++;}}4.哈希表初始化(InitHash)void InitHash(int Hashtable[]){int i;for(i=0;i<LENGTH;i++)Hashtable[i]=-1;}5.向哈希表中插入关键字(InsertHash)void InsertHash(int key,int Hashtable[]){int add;if(Hashtable[add]==-1)Hashtable[add]=key;else{add=Collision(key,Hashtable);Hashtable[add]=key;}}6.查找关键字在哈希表中的存储位置(SearchHash)int SearchHash(int key,int Hashtable[]){int add;add=Hash(key);if(Hashtable[add]==key)return add;while(Hashtable[add]!=key&&Hashtable[add]!=-1)add=Collision(key,Hashtable);return add;}7.输出哈希表(PrintHash)(帮助调试用)void PrintHash(int Hashtable[]){int i;for(i=0;i<LENGTH;i++)if(Hashtable[i]!=-1)printf("%3d:%d\n",i+1,Hashtable[i]);}8.求字符串长度(strlen)(函数库<string.h>包含)以及求整数的绝对值(abs)(函数库<math.h>包含)算法设计:1建立长度为LENGTH的哈希表Hash(LENGTH具体值由宏定义决定)。

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

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

数据结构课程设计报告书班级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; // 声明哈希表Hchar 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指示插入位置,并返回Falseint 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,否则返回Falseint 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 115、测试结果:【程序运行结果】建表和显示:查找:插入:删除:通过分析输入数据和运行结果,证明程序顺利完成实验内容和要求。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

云南大学数学与统计学实验教学中心实验报告课程名称:数据结构与算法学期:2011-2012学年第二学期成绩:指导教师:xxx学生姓名:xxx学生学号:xxxxx实验名称:哈希表及其查找实验要求:必做实验学时:4(+2)学时实验编号:4(及5)实验日期:第6-8周完成日期:2012.5.10学院:数学与统计学院专业:信息与计算科学年级:2010级一、实验目的通过实验掌握散列存储的基本概念,进行哈希问题的处理,同时附带进行字符串的处理的练习。

二、实验内容为某单位的人名(n=30人)设计一个哈希表,使得平均查找长度<2,要求完成相应的哈希建表和查表。

三、实验环境Windows XP程序设计语言C四、实验过程1.实验要求:1、设人名长度<10个字符,用二维字符数组存储哈希表:char hash[ ][10];2、要求哈希函数用除留余数法,并用人名的10个字符代码和作为分子;用(补偿性)线性探测再散列处理冲突。

3、依题意有:平均查找长度=(1+1/(1-α))/2< 2,∴取α=0.6,由此哈希表长m=n/α=30/0.6=50; 所以有char hashlist [ 50][10];令:除留余数法中的P取47;(补偿性)线性探测再散列的地址:j=(j+Q)% m中的Q取17。

4、对程序结构的要求:①要求为哈希建表和哈希查表分别编写和设计相应的函数:createhash( ... ... ); hashsearch(... ...);②再设计一个哈希函数表的输出函数printhash( ),对构造的哈希表进行输出,注意输出格式要在屏幕好看,先输出序号(1~30),再输出该序号的人名或null,每行输出10项,共输出5行。

③还应有一个初始化char hashlist [ 50][10]的函数Inithashlist( ),初始时将50个人名全赋值为null.5、在主函数中:调用Inithashlist( )初始化哈希表;调用createhash( hashlist,30 )构造哈希表;调用printhash( )输出所建立的哈希表;接受待查找人名到字符数组name[ ];调用hashsearch(hashlist,name )进行查找,若查到显示"found!"并显示人名在数组中的序号;若未查到显示"no found!"[测试数据]:健表时输入以下数据:January February march april may june july august septemberOctober November DecemberSunday Monday Tuesday wednesday thurday f riday SaturdayOne two three four five six serve eight nine ten data[实现提示]:参照杨秀清主编《数据结构》西安电子科技大学出版社P171。

[附加要求]:1.在哈希查表时考虑插入。

当查找失败,且查找时的冲突次数<规定数字(如表长之半)时插入待查找的字符串,并给出“已插入”的显示;2.在哈希查表时考虑删除。

接受待删除人名到字符数组name[ ];在hash表中找到,并删除之。

须注意,删除后不能影响以后的查找。

2.实验设计的(各)流程图:(以下内容请同学认真填写)3.程序设计的关键代码及解释:(注意对程序代码给出必要的注解,保证可读性)#include<stdio.h>#define N 50#define D 30#define M 10int m,hi;/*-------------------------------------------------------------------*/main(){void Inithashlist(char a[N][M]);void createhash(char a[D][M],char h[N][M]);void hashsearch(char h[N][M],char a[1][M]);void printhash(char a[][M],int n);char a[M],hashlist[N][M],data[D][M]={/*----------------------------------------------------------*/"January", "February", "March", "April", "May","June", "July", "August", "September", "October","November", "December", "Sunday", "Monday", "Tuesday","Wednesday","Thursday", "Friday", "Saturday", "One","Two", "Three", "Four", "Five", "Six","Serve", "Eight", "Nine", "Ten", "Data"};/*----------------------------------------------------------*/Inithashlist(hashlist);createhash(data,hashlist);printhash(hashlist,50);printf("please enter the name:\n");gets(a);hashsearch(hashlist,a);getchar();getchar();}/*-------------------------------------------------------------------*/void Inithashlist(char a[N][M]){int i;for(i=0;i<N;i++) strcpy(a[i],"null");}/*-------------------------------------------------------------------*//*-------------------------------------------------------------------*/int H(int key,int p){return(key%p);}/*-------------------------------------------------------------------*//*-------------------------------------------------------------------*/void createhash(char a[D][M],char h[N][M]){int i,j,key=0,hi=0,di[N-1];for(i=0;i<N-1;i++) di[i]=i+1;for(i=0;i<D;i++){key=0;j=0;while(a[i][j])key+=a[i][j++];hi=H(key,47);if(!strcmp(h[hi-1],"null")) strcpy(h[hi-1],a[i]);else{m=0;while(strcmp(h[hi-1],"null")) hi=H(hi+17,N);strcpy(h[hi-1],a[i]);}}}/*-------------------------------------------------------------------*//*-------------------------------------------------------------------*/void hashsearch(char h[N][M],char a[M]){char ch2,ch[M]="yes",ch1[M]="yes";int i=0,j,key=0,hi=0;for(;a[i]!='\0';)key+=a[i++];hi=H(key,47);m=0;while(strcmp(h[hi-1],"null")&&strcmp(h[hi-1],a)&&(strcmp(h[hi-1],"Deleted"))) while(strcmp(h[hi-1],"null")) hi=H(hi+17,N);if(!strcmp(h[hi-1],a)){printf("**************\n");printf("found! \n");printf("[%d]%s\n",hi,h[hi-1]);printf("**************\n");while(strcmp(ch1,"No")&&strcmp(ch1,"no")){printf("Delete it?(Y/N)\n");scanf("%s",ch1);ch2=getchar();if(!strcmp(ch1,"Yes")||!strcmp(ch1,"yes")){strcpy(h[hi-1],"Deleted");printf("**************\n");printf("Deleted! \n");printf("**************\n");printhash(h,N);break;}}}else if(m<(N/2)||!(strcmp(h[hi-1],"Deleted"))){strcpy(h[hi-1],a);printf("**************\n");printf("已插入!\n");printf("[%d]%s\n",hi,h[hi-1]);printf("**************\n");printhash(h,N);}else{printf("**************\n");printf("no found!\n");printf("**************\n");}while(strcmp(ch,"No")&&strcmp(ch,"no")){printf("continue to search?(Yes/No)\n");scanf("%s",ch);ch2=getchar();if(!strcmp(ch,"Yes")||!strcmp(ch,"yes")){printf("please enter the name:\n");gets(a);hashsearch(h,a);}}}/*-------------------------------------------------------------------*//*-------------------------------------------------------------------*/void printhash(char a[][M],int n){int i;for(i=0;i<=8;i++){system("color 03");printf("[0%-d] %-11s",i+1,a[i]);if((i+1)%5==0) printf("\n");}for(i=9;i<n;i++){printf("[%-d] %-11s",i+1,a[i]);if((i+1)%5==0) printf("\n");}printf("---------------------");printf("-----------------END-----------------");printf("---------------------\n\n");}/*-------------------------------END---------------------------------*/4.实验(程序运行)结果的粘贴:(必需是你的程序运行结果)[01] Three [02] Nine [03] null [04] null [05] Monday [06] Wednesday [07] null [08] One [09] null [10] Six [11] null [12] null [13] May [14] Ten [15] null [16] null [17] Sunday [18] Five [19] Data [20] null [21] March [22] August [23] Thursday [24] null [25] January [26] June [27] Eight [28] null [29] null [30] October [31] November [32] Two [33] February [34] April [35] Serve [36] Four [37] null [38] null [39] December [40] null [41] null [42] September [43] Friday [44] July [45] null [46] Saturday [47] Tuesday [48] null [49] null [50] null--------------------------------------END--------------------------------------please enter the name:friday**************已插入![28]friday**************.........[26] June [27] Eight [28] friday [29] null [30] October .........--------------------------------------END--------------------------------------continue to search?(Yes/No)yesplease enter the name:friday**************found![28]friday**************Delete it?(Y/N)yes**************Deleted!**************.........[26] June [27] Eight [28] Deleted [29] null [30] October .........continue to search?(Yes/No)please enter the name:friday**************已插入![28]friday**************.........[26] June [27] Eight [28] friday [29] null [30] October.........continue to search?(Yes/No)no五、实验总结1.遇到的问题及分析:(请结合你的试验过程认真总结)①没采用(补偿性)线性探测再散列,导致第二次查找同一元素不能够找到;②删除元素之后用null代替,导致之后的查找操作失败2.解决方案(列出遇到的问题和解决办法,列出没有解决的问题):①改用(补偿性)线性探测再散列;②改用Deleted代替被删元素3.体会和收获。

相关文档
最新文档