您的位置:首页 > 其它

解决散列表冲突问题-分离链接散列表

2017-08-20 23:39 323 查看
分离链接的做法是将同一个值的所有元素放到一个表中

如图



创建分离链接散列表代码

#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;
}


结果

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: