6-4 线性探测法的查找函数(20 分)
试实现线性探测法的查找函数。
函数接口定义:
Position Find( HashTable H, ElementType Key );
其中HashTable
是开放地址散列表,定义如下:
#define MAXTABLESIZE 100000 /* 允许开辟的最大散列表长度 */
typedef int ElementType; /* 关键词类型用整型 */
typedef int Index; /* 散列地址类型 */
typedef Index Position; /* 数据所在位置与散列地址是同一类型 */
/* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */
typedef enum { Legitimate, Empty, Deleted } EntryType;
typedef struct HashEntry Cell; /* 散列表单元类型 */
struct HashEntry{
ElementType Data; /* 存放元素 */
EntryType Info; /* 单元状态 */
};
typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode { /* 散列表结点定义 */
int TableSize; /* 表的最大长度 */
Cell *Cells; /* 存放散列单元数据的数组 */
};
函数Find
应根据裁判定义的散列函数Hash( Key, H->TableSize )
从散列表H
中查到Key
的位置并返回。如果Key
不存在,则返回线性探测法找到的第一个空单元的位置;若没有空单元,则返回ERROR
。
裁判测试程序样例:
#include <stdio.h>
#define MAXTABLESIZE 100000 /* 允许开辟的最大散列表长度 */
typedef int ElementType; /* 关键词类型用整型 */
typedef int Index; /* 散列地址类型 */
typedef Index Position; /* 数据所在位置与散列地址是同一类型 */
/* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */
typedef enum { Legitimate, Empty, Deleted } EntryType;
typedef struct HashEntry Cell; /* 散列表单元类型 */
struct HashEntry{
ElementType Data; /* 存放元素 */
EntryType Info; /* 单元状态 */
};
typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode { /* 散列表结点定义 */
int TableSize; /* 表的最大长度 */
Cell *Cells; /* 存放散列单元数据的数组 */
};
HashTable BuildTable(); /* 裁判实现,细节不表 */
Position Hash( ElementType Key, int TableSize )
{
return (Key % TableSize);
}
#define ERROR -1
Position Find( HashTable H, ElementType Key );
int main()
{
HashTable H;
ElementType Key;
Position P;
H = BuildTable();
scanf("%d", &Key);
P = Find(H, Key);
if (P==ERROR)
printf("ERROR: %d is not found and the table is full.\n", Key);
else if (H->Cells[P].Info == Legitimate)
printf("%d is at position %d.\n", Key, P);
else
printf("%d is not found. Position %d is returned.\n", Key, P);
return 0;
}
/* 你的代码将被嵌在这里 */
输入样例1:(注:-1表示该位置为空。下同。)
11
11 88 21 -1 -1 5 16 7 6 38 10
38
输出样例1:
38 is at position 9.
输入样例2:
11
11 88 21 -1 -1 5 16 7 6 38 10
41
输出样例2:
41 is not found. Position 3 is returned.
输入样例3:
11
11 88 21 3 14 5 16 7 6 38 10
41
输出样例3:
ERROR: 41 is not found and the table is full.
/* 这是一道哈希表的题目,解题思路:Find函数是来寻找我们所要找的关键字是否存在。第一步:把关键字Key和哈希表的表长传到函数Hash中,以此来找到关键字的位置,标记为H0,如果在散列表中第H0个元素存在并且==Key或者第H0个元素位置为空(则证明关键字不在散列表中)就返回元素的位置(即H0)(在寻找关键字的过程中,Key%表长,即关键字在散列表中的位置,如果这个位置有元素存在的话,就用线性探测再散列的方法一次往下寻找位置,直至某个位置是空的,把元素放进去;如果一个数字,在对它第一次做Key%表长时,在散列表中的位置是空的,即证明这个元素根本就不存在,所以就返回第一次运算时得出的位置结果),如果在第一次做%求其位置时,既不是空也不是要找的元素,那就用线性探测的方法继续往下找,找到了就返回元素的位置(即Hi),如果找不到就返回第一次做运算时的位置,否则的话这个表就是空的,就返回ERROR.
/* 这是一道哈希表的题目,解题思路:Find函数是来寻找我们所要找的关键字是否存在。第一步:把关键字Key和哈希表的表长传到函数Hash中,以此来找到关键字的位置,标记为H0,如果在散列表中第H0个元素存在并且==Key或者第H0个元素位置为空(则证明关键字不在散列表中)就返回元素的位置(即H0)(在寻找关键字的过程中,Key%表长,即关键字在散列表中的位置,如果这个位置有元素存在的话,就用线性探测再散列的方法一次往下寻找位置,直至某个位置是空的,把元素放进去;如果一个数字,在对它第一次做Key%表长时,在散列表中的位置是空的,即证明这个元素根本就不存在,所以就返回第一次运算时得出的位置结果),如果在第一次做%求其位置时,既不是空也不是要找的元素,那就用线性探测的方法继续往下找,找到了就返回元素的位置(即Hi),如果找不到就返回第一次做运算时的位置,否则的话这个表就是空的,就返回ERROR.
Position Find( HashTable H, ElementType Key )JI{
Position H0,Hi;
int i;
H0=Hash(Key,H->TableSize);
if(H->Cells[H0].Data==Key || H->Cells[H0].Info==Empty){
return H0;
}
else{
for(i=1;i<H->TableSize;i++)
{
Hi=(H0+i)%(H->TableSize);
if(H->Cells[Hi].Info== Empty || H->Cells[Hi].Data==Key)
return Hi;
}
return ERROR;
}
}