基于拉链法的散列表
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; }
相关文章推荐
- 零基础学python-2.15 回到我们的游戏 加入for以及列表
- 零基础学python-2.15 回到我们的游戏 加入for以及列表
- 零基础学python-2.14 for循环语句
- 零基础学python-2.14 for循环语句
- 零基础学python-在3.x版本之后的print()不换行
- 零基础学python-在3.x版本之后的print()不换行
- Hibernate利用@DynamicInsert和@DynamicUpdate生成动态SQL语句
- AngularJS权威教程(www.Linuxidc.com整理)2
- AngularJS权威教程(www.Linuxidc.com整理)1
- Scala中List的Scala中List和ListBuffer设计实现
- C语言的函数
- 函数调用
- 【LeetCode-面试算法经典-Java实现】【119-Pascal's Triangle II(帕斯卡三角形(杨辉三角)II)】
- 【LeetCode-面试算法经典-Java实现】【118-Pascal's Triangle(帕斯卡三角形)】
- 【LeetCode-面试算法经典-Java实现】【117-Populating Next Right Pointers in Each Node(二叉树链接右指针II)】
- 修改NavigationBar样式
- Android Api Demos登顶之路(三十二)Alarm Service
- 在java中调用python方法
- grep之字符串搜索算法Boyer-Moore由浅入深(比KMP快3-5倍)
- Getting ‘java.net.UnknownHostException: LAPTOP-23876346: nodename nor servname provided, or not know