哈希表又称散列表,是根据关键值而直接进行访问的数据结构。哈希表的实现主要是散列函数和解决冲突。散列函数有:直接寻址法、数字分析法、平法取中法、折叠发、随机数法、除留余数法(严蔚敏版数据结构)。处理冲突的方法有:分离链接法(separate chaining)又称链地址法、开放寻址法、再散列法、建立公共溢出区。本文主要将的是分离链接法的实现。散列函数用的是除留余数法。
编码及测试环境:Visual Studio 2010
fatal.h处理错误的宏定义
#include <stdio.h> #include <stdlib.h> #define FatalError(str) fprintf(stderr, "%s\n", str),exit(1)hashsep.h操作函数的声明
typedef int ElementType; typedef unsigned int Index; #ifndef HASHSEQ_H #define HASHSEQ_H struct Node { ElementType Element; struct Node *Next; }; typedef struct Node *Position; struct HashTbl { int TableSize;//表的大小 Position *TheLists;//存放指针的数组,二级指针 }; typedef struct HashTbl *HashTable; HashTable InitializeTable();//创建hash表 void Insert(ElementType Key, HashTable H);//插入关键字 Position Find(ElementType Key, HashTable H);//查找 void DestoryTable(HashTable H);//销毁hash表 #endifhashsep.c操作函数的实现
#include "fatal.h" #include "hashseq.h" #include <stdlib.h> //hash表的最小值 #define HashTableSize (11) HashTable InitializeTable() { HashTable H; int i; H = (HashTable)malloc(sizeof(struct HashTbl)); if(H == NULL) FatalError("Out of space"); else { H->TableSize = HashTableSize; H->TheLists = (Position *)malloc(sizeof(Position) * H->TableSize); //没有头结点的链表,将指针初始化为NULL for(i = 0 ; i < H->TableSize; i++) H->TheLists[i] = NULL; } return H; } static Index Hash(ElementType Key, int Size) { return Key % Size; } void Insert(ElementType Key, HashTable H) { Position P, TmpCell; Index Val; Val = Hash(Key, H->TableSize); P = H->TheLists[Val]; while(P && P->Element != Key) P = P->Next; //如果表中不存在则采用头插法插入新的Key if(P == NULL) { TmpCell = (Position)malloc(sizeof(struct Node)); TmpCell->Element = Key; TmpCell->Next = H->TheLists[Val]; H->TheLists[Val] = TmpCell; } } Position Find(ElementType Key, HashTable H) { Position P; P = H->TheLists[Hash(Key, H->TableSize)]; while(P && P->Element != Key) P = P->Next; return P; } void DestoryTable(HashTable H) { int i; Position P, Tmp; for(i = 0; i < H->TableSize; i++) { P = H->TheLists[i]; while(P) { Tmp = P->Next; free(P); P = Tmp; } } free(H->TheLists); free(H); }testhash.c测试hash表的实现
#include <stdio.h> #include <stdlib.h> #include "hashseq.h" #define NumItems 400 int main(void) { HashTable H; Position P; int i, j = 0; H = InitializeTable(); for(i = 0; i < NumItems; i++, j += 71) Insert(j, H); for(i = 0, j = 0; i < NumItems; i++, j += 71) if((P = Find(j, H)) == NULL || P->Element != j) printf("Error at %d\n", j); DestoryTable(H); printf("End of program.\n"); system("Pause"); return 0; }