首先是需要定义一个散列表的结构以及一些相关的常数。其实HashTable就是散列表结构。结构当中的elem为一个动态数组。
#define SUCCESS 1
#define HASHSIZE 12 /* 定义散列表长为数组的长度 */
#define NULLKEY -32768
typedef struct
{
int *elem;
int count;
}HahTable;
int m=0;
有了结构的定义,我们可以对散列表进行初始化。
Status InitHashTable (HashTable *H)
{
int i;
m=HASHSIZE;
H->count=m;
H->elem=(int *)malloc(m*sizeof(int));
for(i=0;i<m;i++)
H->elem[i]=NULLKEY;
return OK;
}
为了插入时计算地址,我们需要定义散列函数,散列函数可以根据不同情况更改算法。
int Hash(int key)
{
return key % m;
}
初始化完成后,我们可以对散列表进行插入操作。假设我们插入的关键字集合就是前面的{12,67,56,16,25,37,22,29,15,47,48,34}。
void InsertHash (HahTable *H,int key)
{
int data=Hash(key);
while(H->elem[addr] != NULLKEY)
addr=(addr+1) % m;
H->elem[addr]=key;
}
代码中插入关键字时,首先算出散列地址,如果当前地址不为空关键字,则说明有冲突。此时我们应用开放定址法的线性探测进行重新寻址,此处也可更改为链地址法等其他解决冲突的办法。
散列表存在后,我们在需要时就可以通过散列表查找要的记录。
/* 散列表查找关键字 */
Status SearchHash(HashTable H,int key,int *addr)
{
*addr=Hah(key); /* 求散列地址 */
while(H.elem[*addr]!=key) /* 如果不为空,则冲突 */
{
*addr=(*addr+1) % m; /* 开放定址法的线性探测 */
if(H.elem[*addr] != NULLKEY || *addr==Hah(key))
{/* 如果循环回到原点 */
return UNSUCCESS; /* 则说明关键字不存在 */
}
}
return SUCCESS;
}
查找的代码与插入的代码非常类似,只需做一个不存在关键字的判断而已