哈希表定义及实现
哈希表也叫散列表,是快速执行查找,删除,插入的技术,不支持元素排序信息。原理是通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。
关键码值到存储位置的映射被称为哈希函数也叫散列函数,当不同关键key被映射到同一value时,称为冲突。
解决冲突主要有:
分离链接法:对Hash表中每个Hash值建立一个冲突表,即将冲突的几个记录以表的形式存储在其中。
开发定址法:根据冲突算法找到空的单元为止(线性探测法,平方探测法…)。
编程实例
算法实现
采用平方探测法的实现放在git@code.aliyun.com:c-program/projecteuler.git上projecteulerccommonstruct目录下elr_hash_int.h elr_hash_int.c两个单元内。
解决问题
https://www.hackerrank.com/ch…
要求用一个map结构存放名字name和电话phone。
定义结构
#define MaxStr 20
typedef unsigned long int Index;
typedef Index Position;
typedef char *KeyType;
typedef long int *ValueType;
struct HashTbl;
typedef struct HashTbl *HashTable;
enum KindOfEntry { Legitimate, Empty, Deleted };
struct HashEntry {
KeyType Key;
ValueType Value;
enum KindOfEntry Info;
};
typedef struct HashEntry Cell;
struct HashTbl {
long int TableSize;
Cell *TheCells;
};
初始化及释放
HashTable InitializeTable(long int TableSize) {
HashTable H;
long int i;
H = malloc(sizeof(struct HashTbl));
if (H == NULL) {
printf("Out of space!\n");
}
H->TableSize = TableSize;
H->TheCells = malloc(sizeof(Cell) * H->TableSize);
if (H->TheCells == NULL) {
printf("Out of space!\n");
}
for (i = 0; i < H->TableSize; i++) {
H->TheCells[i].Info = Empty;
H->TheCells[i].Key = NULL;
H->TheCells[i].Value = 0;
}
return H;
}
void DestroyTable(HashTable H) {
int i;
if (H == NULL) {
return;
}
for (i = 0; i < H->TableSize; i++) {
H->TheCells[i].Info = Empty;
if (H->TheCells[i].Key != NULL) {
free(H->TheCells[i].Key);
}
}
free(H);
}
哈希及冲突插入操作
Position Hash(KeyType Key, long int TableSize) {
long int keyValue = 0;
register unsigned char *p;
for (p = (unsigned char *)Key; *p; p++) {
keyValue = 31 * keyValue + *p;
}
return keyValue % TableSize;
}
int KeyEqual(KeyType a, KeyType b) {
if ((a == NULL) || (b == NULL)) {
return 1;
}
return strcmp(a, b) == 0 ? 0 : 1;
}
int Find(KeyType Key, HashTable H, Position *Pos) {
Position CurrentPos;
long int CollisionNum;
int rst = 0;
CollisionNum = 0;
CurrentPos = Hash(Key, H->TableSize);
while (1) {
if (H->TheCells[CurrentPos].Info == Empty)
break;
if (KeyEqual(H->TheCells[CurrentPos].Key, Key) == 0) {
rst = 1;
break;
}
CurrentPos += (++CollisionNum << 1) - 1;
if (CurrentPos >= H->TableSize) {
CurrentPos -= H->TableSize;
}
}
*Pos = CurrentPos;
return rst;
}
void Insert(KeyType Key, ValueType Value, HashTable H) {
Position Pos;
int exist;
exist = Find(Key, H, &Pos);
H->TheCells[Pos].Info = Legitimate;
if (!exist) {
H->TheCells[Pos].Key = malloc(sizeof(char) * MaxStr);
}
strcpy(H->TheCells[Pos].Key, Key);
H->TheCells[Pos].Value = Value;
}
调用解决问题
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
long int n = 0;
scanf("%ld", &n);
HashTable H = InitializeTable(n * 2);
for (int i = 0; i < n; i++) {
char name[20];
long int phone;
scanf("%s %ld", name, &phone);
Insert(name, phone, H);
}
for (int i = 0; i < n; i++) {
char name[20];
Position Pos;
int exist;
scanf("%s", name);
// while (() != '\n');
exist = Find(name, H, &Pos);
if (exist == 1) {
ValueType Value = H->TheCells[Pos].Value;
printf("%s=%ld\n", name, Value);
} else {
printf("Not found\n");
}
if (getchar() == EOF)
break;
}
DestroyTable(H);
return 0;
}
发表回复