常用的解决哈希冲突的方法有两种:
一、开放定址法:开放定址法是一类以发生冲突的哈希地址为自变量,通过某种哈希冲突函数得到一个新的空闲地址的方法。
在开放定址法中常用的有线性探查法和平法探查法;线性探查容易产生堆积问题。而平方探查法可以解决堆积问题,但不能探查到哈希表上的所有单元,但至少能探查到一本单元
二、拉链法:拉链法是把所有的同义词用单链表链接起来的一种方法,与开放定址法相比有以下优点:
(1)、处理冲突简单,且无堆积现象,即非同义词不会发生冲突,因此平均查找长度较短;
(2)、由于拉链法中各链表上的记录空间是动态申请的,故更适合于造表前无法确定表长的情况;
(3)、删除记录容易
缺点是需要额外的空间,故当记录较多时可以用拉链法;
以下为拉链法的C++代码:
#include <iostream>
typedef struct _Node
{
int data;
struct _Node *next;
}NODE,*PNODE;
typedef struct _HASH_TABLE
{
PNODE value[10];
}HASH_TABLE, *PHASH_TABLE;
PHASH_TABLE create_hash_table()
{
PHASH_TABLE pHashTable = (PHASH_TABLE)malloc(sizeof(HASH_TABLE));
memset(pHashTable,0,sizeof(HASH_TABLE));
return pHashTable;
}
PNODE find_data_in_hash(PHASH_TABLE pHashTbl,int data)
{
PNODE pNode;
if (NULL == pHashTbl)
{
return NULL;
}
/*获得HASH表索引,为NULL则直接返回NULL*/
if (NULL == (pNode = pHashTbl->value[data%10]))
{
return NULL;
}
/*在该索引下的单链表中查找节点*/
while(pNode)
{
if ( data == pNode->data)
{
/*找到节点就返回当前节点*/
return pNode;
}
/*当前节点不是,指向下一节点*/
pNode = pNode->next;
}
/*没找到返回NULL,不过在这返回没有意义*/
return NULL;
}
bool insert_data_into_hash(PHASH_TABLE pHashTbl,int data)
{
PNODE pNode;
if (NULL == pHashTbl)
{
return false;
}
if (NULL == pHashTbl->value[data%10])
{
pNode = (NODE*)malloc(sizeof(NODE));
memset(pNode,0,sizeof(NODE));
pNode->data = data;
pHashTbl->value[data%10] = pNode;
return true;
}
if (NULL != find_data_in_hash(pHashTbl,data))
{
return false;
}
pNode = pHashTbl->value[data%10];
while(pNode->next)
{
pNode = pNode->next;
}
pNode->next = (NODE*)malloc(sizeof(NODE));
memset(pNode->next,0,sizeof(NODE));
pNode->next->data = data;
return true;
}
bool delete_data_from_hash(PHASH_TABLE pHashTbl,int data)
{
PNODE pHead;
PNODE pNode;
if (NULL == pHashTbl || NULL == pHashTbl->value[data%10])
{
return false;
}
if (NULL == (pNode = find_data_in_hash(pHashTbl,data)))
{
return false;
}
if (pNode == pHashTbl->value[data%10])
{
pHashTbl->value[data%10] = pNode->next;
free(pNode);
return false;
}
pHead = pHashTbl->value[data%10];
while(pNode != pHead->next)
{
pHead = pHead->next;
}
pHead->next = pNode->next;
return true;
}
/****************************************
f)打印hash表中所有数据
如:
[Hash idx] [value]
0-------------NULL
1-------------1 251
2-------------22
3-------------123 43
4-------------NULL
5-------------55 15 235 525 725 275 545
6-------------NULL
7-------------257
8-------------NULL
*****************************************/
void print_hash_data(HASH_TABLE* pHashTbl)
{
NODE* pNode;
int i=0;
if (NULL == pHashTbl)
{
printf("ERROR:The hash is NULL\n");
}
/*
if (NULL == (pNode = pHashTbl->value[10]))
{
printf("ERROR:The hash node is NULL\n");
}
*/
printf("[Hash idx] [value]\n");
do
{
printf(" %d-------------",i);
if (NULL == pHashTbl->value[i])
{
i++;
printf("NULL\n");
continue;
}
pNode = pHashTbl->value[i];
while(pNode)
{
printf("%d ",pNode->data);
pNode = pNode->next;
}
printf("\n");
i++;
} while (i<10);
printf("\n");
}
int main()
{
HASH_TABLE* pHashTbl = create_hash_table();
(void)insert_data_into_hash(pHashTbl,22);
(void)insert_data_into_hash(pHashTbl,22);
(void)insert_data_into_hash(pHashTbl,123);
(void)insert_data_into_hash(pHashTbl,436);
(void)insert_data_into_hash(pHashTbl,55);
(void)insert_data_into_hash(pHashTbl,157);
(void)insert_data_into_hash(pHashTbl,235);
(void)insert_data_into_hash(pHashTbl,256);
(void)insert_data_into_hash(pHashTbl,525);
(void)insert_data_into_hash(pHashTbl,724);
(void)insert_data_into_hash(pHashTbl,278);
(void)insert_data_into_hash(pHashTbl,209);
(void)insert_data_into_hash(pHashTbl,67);
(void)insert_data_into_hash(pHashTbl,54);
(void)insert_data_into_hash(pHashTbl,546);
(void)insert_data_into_hash(pHashTbl,350);
(void)insert_data_into_hash(pHashTbl,101);
(void)insert_data_into_hash(pHashTbl,23);
print_hash_data(pHashTbl);
(void)delete_data_from_hash(pHashTbl,55);
print_hash_data(pHashTbl);
system("pause");
return 1;
}