链地址法
设计思路:节点存储和原数值它的下一个节点,将每一个数组存储节点,其下标为其哈希值,节点指向所有和它冲突的值
此代码运算哈希值的运算公式 f(x)=x%14
当然也可以通过别的函数运算其哈希值,由于哈希值会直接作为下标,因而其哈希值尽量控制在0-15之间,如若哈希表过长则会造成空间的浪费,一般来说 数据个数/0.75 > 哈希表长,比较适宜。
== 2020.1.20 在这个特殊的日子,我决定痛改前非给你们解释一下我的代码(新增了许多注释帮助理解)。由衷地希望有更多的人能够了解我的思路并且让完全不懂的人对编程有一点点希望。 ==
#include<stdio.h>
#include<stdlib.h>
typedef struct h
{
int n; //表示的是一个数字,原本未处理的数据(将要存储在哈希表中的数据)
struct h *next;
/*一旦出现冲突,即有两个值经过运算后,哈希值相同时,这个值存储在next域
里面,为了使得顺序也按照原来的顺序排列,故在后面的代码里是运用了尾插法,
每一插入的值都在这个下标位置的链的最后一个*/
}node,*List;
//a[] 待处理的原数组 n 原数组的有效数据个数 m 转化成的哈希表的表长
List hash(int a[],int n,int m)
{
int i,j,index;
node *b[15]={NULL},*p,*q;
for(i=0;i<n;i++)
{
index=a[i]%14; //将每一个数据经过哈希函数处理,得到的值为下标
//b数组里面的每一个在初始化后都是NULL,因而当对应下标当中为空的时候那么
if(b[index]==NULL)
{
b[index] = malloc(sizeof(node));
b[index]->n =a[i];
b[index]->next=NULL;
}
else
{
p=b[index];
while(p->next!=NULL)
{
p=p->next;
}
p->next = malloc(sizeof(node));
p=p->next;
p->n=a[i];
p->next=NULL;
}
}
for(i=0;i<m;i++)
{
p=b[i];
while(p!=NULL)
{
printf("%d\t %d\t \n",p->n,i);
p=p->next;
}
}
return b[0];
}
int main()
{
int n_suf=12; //有效的数字个数
int length=15; //存储的哈希表表长
int arr[15]={105,97,28,52,37,22,16,9,45,79,59,76};
hash(arr,n_suf,length);
}