您的位置:首页 > 其它

基于拉链法的散列表

2015-08-13 07:03 330 查看
#include <stdio.h>

//基于拉链法的散列表
//散列表通常一个难点就是出现键冲突后,如果进行冲突解决,
//基于拉链法的散列表给每个键分配一个链表,当出现键冲突时,
//将冲突键的条目项都挂接到一个链表下,从而解决了键冲突问题。

#define MAX_HASH_ARRAY  50

typedef struct _HASH_NODE
{
int                 key;
int                 val;
struct _HASH_NODE*  next;
} HASH_NODE;

//这里采用了拉链法解决链冲突问题,当使用哈希函数计算,出现了相
//同KEY时,将相同项存储到一个链表中。
HASH_NODE* hashTable[MAX_HASH_ARRAY] = {0};

//正整数类型的KEY的散列函数
//通常采用除留余法,这里通过对KEY进行求余,使得KEY分布在hashTable
//的数组中,同时为了减少键冲突,除数通常选择为素数,比如当前示例
//选择为97
int hashFunctionForInt(int key)
{
// M 通常为素数
//hashKey = key % M
int hashKey = key % 97;
return hashKey;
}

//字符串类型的KEY的散列函数
//这里也采用了除留余法
int hashFunctionForStr(char *string)
{
int hashKey = 0;
int i = 0;

for ( i = 0; i < strlen(string); i++ )
{
// R 在这里相当于将字符串当作一个N位的R进制值,比如这里
// 取R值为10,假设当前string为“123”,通过R的处理,相当
// 于这个字符串输出了整数123,即100 * 1 + 10 * 2 + 3
// M 通常为素数,这里取值为31是为了使得字符串中所有字
// 符都能启到关键作用
//hashkey  = (R * hashKey + string[i]) % M
hashKey = (10 * hashKey + string[i])  % 31;
}

return hashKey;
}

//计算哈希表数组的索引
// 1首先算出hashKey
// 2 之后根据当前哈希表数组长度进行求余操作,避免计算出来的hashKey大于
//  数组长度,导致出现溢出
int hashIndex(int key)
{
int hashKey = hashFunctionForInt(key);
return hashKey % MAX_HASH_ARRAY;
}

//插入操作
//根据当前key计算出所在哈希表数组的索引,将新的条目插入到该数组索
//引的链表中
void put(int key, int val)
{
int        index = hashIndex(key);
HASH_NODE* pNewNode = (HASH_NODE*)malloc(sizeof(HASH_NODE));
if ( pNewNode == NULL )
{
printf("failed to malloc.\r\n");
return;
}

memset(pNewNode, 0, sizeof(HASH_NODE));
pNewNode->key = key;
pNewNode->val = val;

pNewNode->next = hashTable[index];
hashTable[index] = pNewNode;
}

//查找操作
//根据当前key计算出所在的哈希表数组索引,之外遍历当前数组索引对应的
//链表,找出与当前key相同的条目,这里之所有遍历,是因为在进行hashIndex
//计算时,可能会出现不同key有相同数组索引的情况,即键冲突。
int get(int key)
{
int val = -1;
int index = hashIndex(key);
HASH_NODE* pCurHashNode = hashTable[index];

while ( pCurHashNode )
{
if ( pCurHashNode->key == key )
{
val = pCurHashNode->val;
break;
}

pCurHashNode = pCurHashNode->next;
}

return val;
}

int getChainCount(HASH_NODE* pNode)
{
int count = 0;

while ( pNode != NULL )
{
count++;
pNode = pNode->next;
}

return count;
}

void showHashTable()
{
int i = 0;

printf("-- showHashTable ------------------------\r\n");

for ( i = 0; i < MAX_HASH_ARRAY; i++ )
{
HASH_NODE* pHashNode = hashTable[i];
int chainCount = getChainCount(pHashNode);

if ( chainCount > 0 )
{
printf("chain %d(%d):\r\n", i, chainCount);

while (pHashNode != NULL)
{
printf("  key %d, val %d\r\n", pHashNode->key, pHashNode->val);
pHashNode = pHashNode->next;
}
}
}

printf("-----------------------------------------\r\n");
}

int main()
{
put(3, 3);
put(6, 6);
put(25, 25);
put(29, 29);
put(17, 17);

showHashTable();

printf("get key %d, val %d\r\n", 14, get(14));
printf("get key %d, val %d\r\n", 25, get(25));

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