分离链接的做法是将同一个值的所有元素放到一个表中
如图
创建分离链接散列表代码
#include<stdio.h>
#include<stdlib.h>
typedef struct ListNode
{
int Element;
struct ListNode *next;
}List;
typedef struct HashTb1
{
int TableSize;
List *TheLists;
}HashTable;
//函数声明
HashTable InitializeTable(int TableSize);
HashTable CreateHashTable(int Element, HashTable H);
void PrintfHashTable(HashTable H);
void FreeHashTable(HashTable H);
int main()
{
HashTable H;
int i;
int h[10] = {1, 0, 4, 16, 25, 64, 81, 9, 49, 36};
H = InitializeTable(10);
for(i = 0; i < 10; i++)
{
H = CreateHashTable(h[i], H);
}
PrintfHashTable(H);
FreeHashTable(H);
return 0;
}
HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;
H.TableSize = TableSize;
//Allocate array of lists
H.TheLists = (List*) malloc(sizeof(List)*TableSize);
if(H.TheLists == NULL)
{
printf("Out of space !!");
exit(1);
}
for(i = 0; i < TableSize; i++) //初始化散列表的表头
{
H.TheLists[i].next = NULL;
H.TheLists[i].Element = i; //将表头元素定义为此表模值
}
return H;
}
HashTable CreateHashTable(int Element, HashTable H)
{
int TempM, i;
//通过模运算找到合适的位置
TempM = Element % 10;
//动态创建List结构体
List *L = (List*)malloc(sizeof(List));
//将关键字存入相应的表中
for(i = 0; i < H.TableSize; i++)
{
if(H.TheLists[i].next == NULL) //只有表头的情况
{
if(TempM == H.TheLists[i].Element)
{
H.TheLists[i].next = L;
L->Element = Element;
L->next = NULL;
return H;
}
}
else
{
if(TempM == H.TheLists[i].Element) //表中已经有元素的情况,头插
{
L->next = H.TheLists[i].next;
H.TheLists[i].next = L;
L->Element = Element;
return H;
}
}
}
}
void PrintfHashTable(HashTable H)
{
int i;
List *L;
for(i = 0; i < H.TableSize; i++)
{
//先输出该行模
printf("%d ", H.TheLists[i].Element);
if(H.TheLists[i].next != NULL)
{
L = H.TheLists[i].next;
do
{
printf("%d ",L->Element);
L = L->next;
}while(L != NULL);
}
printf("\n\n");
}
}
void FreeHashTable(HashTable H)
{
int i;
List *L, *Tmp;
for(i = 0; i < H.TableSize; i++)
{
if(H.TheLists[i].next != NULL)
{
L = H.TheLists[i].next;
Tmp = H.TheLists[i].next;
do
{
free(L);
L = Tmp->next;
Tmp = L;
}while( L != NULL);
}
free(H.TheLists);
}
}
输出结果
创建好散列表之后,再添加一些后序操作,就比原来那个散乱无章的集合更容易实现功能。
Find 功能实现
void Find(int X, HashTable H)
{
int i;
int Tag = 0;
List *L;
for(i = 0; i < H.TableSize; i++)
{
if(H.TheLists[i].next != NULL)
{
L = H.TheLists[i].next;
do
{
if(L->Element == X)
{
//输出被查找到的X的信息
printf("%d is in the %d List , positon is %d\n", X, H.TheLists[i].Element, L);
return;
}
L = L->next;
}while(L != NULL);
}
}
printf("Sorry, No Fund!\n");
return;
}
结果
Insert函数实现
Insert的实现与创建散列表类似
HashTable Insert(int X, HashTable H)
{
int TempM, i;
//通过模运算找到合适的位置
TempM = X % 10;
//动态创建List结构体
List *L = (List*)malloc(sizeof(List));
//将关键字存入相应的表中 ,头插法
for(i = 0; i < H.TableSize; i++)
{
if(TempM == H.TheLists[i].Element)
{
L->next = H.TheLists[i].next;
H.TheLists[i].next = L;
L->Element = X;
return H;
}
}
}
结果
Delete操作
HashTable Delete(int X, HashTable H)
{
List *L;
List *Temp;
int i;
for(i = 0; i < H.TableSize; i++)
{
L = H.TheLists[i].next;
Temp = H.TheLists;
if(H.TheLists[i].next != NULL)
{
do
{
if(L->Element == X)
{
Temp->next = L->next;
free(L);
return H;
}
Temp = L;
L = L->next;
}while(L != NULL);
}
}
printf("NO element to delete!\n");
return H;
}
结果