//构造hash算法:
//1.直接定址法 H(key) = key 或者 H(key) = a*key + b;
//2.数字分析法
//3.平方取中法: 将数据key进行平方,根据情况随意取数据的中间几位即可
//4.折叠法: 将数据分割成位数较小的几分,然后将几份数据进行叠加。456 789 12 ——>456 789 120 以上三者相加
//5.除留余数法: H(key) = key MOD p, p<=N (N为表长)
//6.随机数法: H(key) = random(key) random为随机函数
//key1 != key2 —> H(key1) == H(key2),称之为冲突
//解决冲突的方法:
//1.开放定址法 H(key) = ( H(key)+di ) MOD m i=1,2,3…k(k<=m-1)
//a.di = 1,2,3,…m-1,称为线性探测再散列
//b.di = 1*1 ,-1*1,2*2, -2*2…-k*k (k<=m/2),称之为二次探测再散列
//c.di = 伪随机数序列, 称之 伪随机探测再散列
//2.再hash法 Hi = RH(key) i = 1,2,3,…,k
//3.链地址法
//4.建立公共溢出区
实例一
//////////////////////////////hash表实现例子////////////////////////////////////////////
//////////////////表长为N,采用除留余数法构造hash算法,开放地址法解决冲突///////////////
#include <stdio.h>
#define N 4
typedef int datatype;
typedef struct
{
datatype key;
}HashTable;
int Hashsearch(HashTable *HT, datatype k)
{
int addr,i=0;
addr = k % N;//除留余数法:H(key) = key MOD p,p<=N (N为表长)
while(i<N && HT[addr].key != -1 && HT[addr].key != k)
{
i++;
addr = (addr+1)%N; //产生冲突,采用开放地址法中的线性探测再散列
}
if(i == N)
return -1; //表溢出
else
{
return addr;//插入地址 下标
}
}
int HashInsert(HashTable *HT, datatype R)
{
int addr;
addr = Hashsearch(HT, R);//找到要插入的位置:不产生冲突
//如果hash表的数据溢出-1,或者表中的数据与要插入的数据一致,返回
//否则,直接插入数据
if(addr==-1 || HT[addr].key == R)
{
return 1;
}
else
{
HT[addr].key = R;
printf("%d ",HT[addr].key);
return 0;
}
}
int main()
{
HashTable HT[N];//hash表,长度为N
for(int i=0;i<N;i++)//初始化hash表,表中数据
HT[i].key = -1;
for(int i=0;i<20;i++)//数据插入到hash表
{
int value = HashInsert(HT,i+200);
if(value)
printf("表溢出或记录已存在!\n");
else
{
printf("插入成功!\n");
}
}
//打印hash表
for(int i=0;i<N;i++)
{
printf("%d ",HT[i].key);
}
printf("\n");
getchar();
return 0;
}
实例二
//散列表查找算法(Hash)
#include <stdio.h>
#include <stdlib.h>
#define OK 1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define SUCCESS 1
#define UNSUCCESS 0
#define HASHSIZE 7
#define NULLKEY -32768
typedef int Status;
typedef struct
{
int *elem; //基址
int count; //当前数据元素个数
}HashTable;
int m=0; // 散列表表长
/*初始化*/
Status Init(HashTable *hashTable)
{
int i;
m=HASHSIZE;
hashTable->elem = (int *)malloc(m * sizeof(int)); //申请内存
hashTable->count=m;
for (i=0;i<m;i++)
{
hashTable->elem[i]=NULLKEY;
}
return OK;
}
/*哈希函数(除留余数法)*/
int Hash(int data)
{
return data % m;
}
/*插入*/
void Insert(HashTable *hashTable,int data)
{
int hashAddress=Hash(data); //求哈希地址 //发生冲突
while(hashTable->elem[hashAddress]!=NULLKEY)
{ //利用开放定址的线性探测法解决冲突
hashAddress=(++hashAddress)%m;
} //插入值
hashTable->elem[hashAddress]=data;
}
/*查找*/
int Search(HashTable *hashTable,int data)
{
int hashAddress=Hash(data); //求哈希地址 //发生冲突
while(hashTable->elem[hashAddress]!=data)
{ //利用开放定址的线性探测法解决冲突
hashAddress=(++hashAddress)%m;
if (hashTable->elem[hashAddress]==NULLKEY||hashAddress==Hash(data))
return -1;
} //查找成功
return hashAddress;
}
/*打印结果*/
void Display(HashTable *hashTable)
{
int i;
printf("\n//==============================//\n");
for (i=0;i<hashTable->count;i++)
{
printf("%d ",hashTable->elem[i]);
}
printf("\n//==============================//\n");
}
int main()
{
int i,j,result;
HashTable hashTable;
int arr[HASHSIZE]={28,29,28,28,26,30,38};
printf("***************Hash哈希算法***************\n");
//初始化哈希表
Init(&hashTable);
Display(&hashTable);
//插入数据
for (i=0;i<HASHSIZE;i++)
{
Insert(&hashTable,arr[i]);
}
Display(&hashTable);
//查找数据
result= Search(&hashTable,89);
if (result==-1)
printf("对不起,没有找到!\n");
else
printf("89在哈希表中的位置是:%d\n",result);
system("pause");
return 0;
}