基于C的链地址法哈希表搜索函数返回错误值问题排查
链地址法哈希表搜索异常问题排查
我在算法课程作业中用C语言实现链地址法哈希表,哈希函数采用基于Knuth常数((√5)-1)/2的乘法哈希,键的哈希计算确认正确,但调用搜索函数时,返回值和插入时的预期不符。想排查下Node**数组的使用是否存在错误,以下是我的实现代码:
初始化哈希表
void * AllocateChainTable(int elementCountMax) { Node ** array = calloc(elementCountMax, sizeof(Node *)); for (int i = 0; i < elementCountMax; i++) { array[i] = initList(); } return array; }
插入函数
int InsertChain( void * hashtable, int elementSize, int elementCountMax, int key, void * element, int (*HashFunc)(int key)) { Node ** hashTable = hashtable; int hashedKey = HashFunc(key); insertAtHead(hashTable[hashedKey], element, key); return 0; }
链表头插函数(带哑节点)
void insertAtHead(Node * node, void * data, int key) { int error = 0; Node * new = createNode(data, &error, key); if (error == 1) { return; } if (node->next == NULL) { node->next = new; int * size = (int *)node->data; *size++; return; } Node * oldHead = node->next->next; node->next = new; new->next = oldHead; int * size = (int *)node->data; *size++; }
搜索函数
void * SearchChain(void * hashtable, int key, int elementSize, int (*HashFunc)(int key)) { Node ** hashTable = hashtable; int hashKey = HashFunc(key); if (hashTable[hashKey]->next != NULL) { Node * startingNode = hashTable[hashKey]->next; while (startingNode != NULL) { if (startingNode->key == key) { return startingNode->data; } else { startingNode = startingNode->next; } } } return NULL; }
问题排查结论
Node**数组的使用本身没有错误,问题出在insertAtHead函数的实现上:
- 头插逻辑错误:
原代码中Node * oldHead = node->next->next;会跳过当前链表的第一个有效节点,导致新插入的节点直接连接到第二个有效节点之后,第一个节点丢失。正确的头插应该保存当前的头节点node->next,再将新节点的next指向这个旧头节点。 - size自增操作错误:
*size++;因运算符优先级问题,实际执行的是*(size++),只会移动指针而不会修改原size变量的值,正确写法应为(*size)++;,先解引用再自增。
修正后的insertAtHead函数
void insertAtHead(Node * node, void * data, int key) { int error = 0; Node * new = createNode(data, &error, key); if (error == 1) { return; } // 保存原有头节点,完成头插 Node * oldHead = node->next; node->next = new; new->next = oldHead; // 正确更新链表大小 int * size = (int *)node->data; (*size)++; }
内容的提问来源于stack exchange,提问作者QuantumBlink
相关产品推荐
相关产品推荐

