一. 分析
1. 确定哈希函数-六种方法
- 1. 直接地址法: 取关键字或关键字的某个线性函数值做为哈希地址。
H(key) = key
H(key) = a * key +b
- 2. 数字分析法
- 3. 平方取中法
- 4. 折叠法
- 5. 除留余数法
- 6. 随机数法
2. 解决哈希冲突
1. 开发地址法
- 1. 线性探测(+1,2,3,4,5,6.。。)
- 2. 线性补偿探测,按找一定步长找位置
- 3. 随即探测
- 4. 线性探测再散列(+-1, +-4, +-9,+-16。。。)
2. 拉链法
同一个hash值,在下面加个链表(头添加)
二. 例子: 直接地址法+拉链法
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct hash
{
int nValue; //装 原数值
int nIndex; //哈系表中的值(012345)/nValue在原书组中的位置!
struct hash* pNext;
}Hash;
Hash* * CreateHashTable(int* arr, int nLength,int M)
{
if(arr == NULL || nLength <= 0) return NULL;
//哈希表指针
Hash* * pHashTable = (Hash**)malloc( sizeof(Hash*)* M);
memset(pHashTable, 0 ,sizeof(Hash*)*M);
int nIndex;
//遍历数组, 把数据放入表中
for(int i =0 ;i<nLength; i++)
{
nIndex = arr[i]%M; //得到哈西值;
Hash* pTemp = (Hash*)malloc( sizeof(Hash));
pTemp->nValue = arr[i];
pTemp->nIndex = i; //该数字在原数组的位置
//头添加,pHashTable[nIndex] 是Hash× 类型;(×pHead的感觉)
pTemp->pNext = pHashTable[nIndex];//头添加
pHashTable[nIndex] = pTemp;
}
return pHashTable;
}
//Hash表查找,返回待查数据,在原数组中的位置!
int HashSearch(int* arr, int nLength, Hash* *pHashTable, int nFindNumber,int M)
{
if(!arr||nLength <=0||!pHashTable)
//1. 得到哈希值
int nIndex = nFindNumber%M;
//2. 根据哈希值找到元素所在链表
Hash* pTemp = pHashTable[nIndex];
//3. 遍历链表
while(pTemp)
{
if(pTemp->nValue == nFindNumber)
{
return pTemp->nIndex;
}
pTemp = pTemp->pNext;
}
return -1;
}
int main()
{
int arr[] = {20,4,38,105,92,49,7,16,25,32,51,1,116};
Hash* *ph = CreateHashTable(arr, sizeof(arr)/4,13);
int n = HashSearch(arr, sizeof(arr)/4,ph, 16,13);
printf("%d \n",n);
n = HashSearch(arr, sizeof(arr)/4,ph, 16,123);
printf("%d \n",n);
return 0;
}