查找算法中 hash查找是最快的.但是它需要先构造hash表,构造hash表之后利用hash函数在hash表中查找的速度是非常迅速的 所以时间复杂度是O(1)
最常用的构造散列函数的方法是: 除留余数法
F(key) = key mod P (P <= M)
若散列表的长度是M, 通常p为小于或等于表长(最好接近于m)的最小质数,或不包含小于20质因子的合数.hash表的生成和查找都会存在冲突问题, 解决冲突的方法有很多,这里采用 开放定址法即线性探测法
Fi(key) = ( F(key) + Di ) mod M (Di = 1,2,3,4,…,M-1)
c语言代码如下
//hash表的生成和查找
//hash函数是 除留余数法
//冲突采用 开放定址法 线性探测
#include<stdio.h>
#include<stdlib.h>
#define ERROR 0
#define OK 1
#define HASHSIZE 12
#define NULLKEY -32768 //初始化的默认值
#define arr_length(array) (sizeof(array)) / (sizeof(array[0])); //定义一个宏 求数组长度
typedef int Status;
typedef struct{
int *elem; //数据元素的存储基址
int count; //当前数据元素的个数
} HashTable;
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; //除留余数法
}
//插入关键字进散列表
void insertHash(HashTable *H, int key){
int addr = hash(key); //求散列地址
while(H->elem[addr] != NULLKEY){ //冲突产生了.
addr = (addr + 1) % m; //开放定址法 线性探测
}
H->elem[addr] = key; //如果有空位插入关键字
}
//散列表查找关键字 用*addr返回
Status searchHash(HashTable H, int key, int *addr) {
*addr = hash(key);
while(H.elem[*addr] != key){ //有冲突,向下查找
*addr = (*addr + 1) % m;
if(H.elem[*addr] == NULLKEY || *addr == hash(key)){ //循环回到原点 说明关键字不存在
printf("查找的关键字不存在\n");
return ERROR;
}
}
return OK;
}
int main(void){
int array[12] = {12,67,56,16,25,37,22,29,15,47,48,34};
HashTable H;
initHashTable(&H);
printf(" 1.初始化散列表\n 2.插入散列值\n 3.查找\n 0.退出\n");
int option = 1, key;
int i, length, addr, res;
while(option){
scanf("%d", &option);
switch(option){
case 1:
res= initHashTable(&H);
if(res == OK){
printf("初始化成功!\n");
}
break;
case 2:
initHashTable(&H);
length = arr_length(array) - 1;
for(i = 0; i < length; i++){
insertHash(&H, array[i]);
}
printf("插入成功\n");
break;
case 3:
printf("请输入要超找的关键字\n");
scanf("%d", &key);
res = searchHash(H, key, &addr);
if(res == OK){
printf("查找成功 关键字的下标是 %d\n", addr);
}
break;
case 0:
return OK;
default:
printf(" 1.初始化散列表\n 2.插入散列值\n 3.查找\n 0.退出\n");
break;
}
}
return 0;
}
上述代码产生的hash表如下
下标 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
关键字 | 12 | 25 | 37 | 15 | 16 | 29 | 48 | 67 | 56 | 34 | 22 | 47 |
版权声明:本文为博主原创文章,未经博主允许不得转载。
原文地址:http://blog.csdn.net/u010187139/article/details/46971099