C语言链表哈希表两次调用print函数后数据丢失求助
哈希表打印后数据丢失问题排查
我实现了一个哈希表,由包含10个元素的数组构成,每个元素作为链表头节点。插入数据后第一次打印哈希表正常,但再次选择打印时,哈希表中数据全部丢失,所有值均为NULL。怀疑问题出在print函数,尝试用辅助变量遍历数组打印但没解决。
感谢任何形式的帮助!
#include <stdio.h> #include <stdlib.h> typedef struct no{ int id; char name; struct no *next; }no; void insert(no * vetor, int idInsert, char nameInsert, int pinsert){ no *newNo = (no*)malloc(sizeof(no)); newNo->id = idInsert; newNo->name = nameInsert; newNo->next = NULL; if ((vetor[pinsert]).next == NULL){ (vetor[pinsert]).next = newNo; return;} newNo -> next = (vetor[pinsert].next); vetor[pinsert].next = newNo; } void printVetor(no * vetor){ no * vetoraux = vetor; for (int n = 0; n<= 9; n++){ if(vetoraux[n].next == NULL){ printf("->[NULL]\n");} else{ do{ printf("-> [id: %d] ", (vetoraux[n]).next->id); (vetoraux[n]).next = (vetoraux[n]).next -> next; } while ((vetoraux[n]).next != NULL); printf("-> [NULL]\n"); } } } int main(){ no vetor[10]; for (int n = 0; n<= 9; n++){ (vetor[n]).next = NULL;} int option; do{ printf("1-insert ints \n2-print hashtable\n5-esc\n"); scanf("%d", &option); switch (option){ case 1: insert(vetor, 10, 'c', 2); insert(vetor, 20, 'c', 2); insert(vetor, 30, 'c', 3); insert(vetor, 40, 'c', 3); break; case 2: printVetor(vetor); break; case 5: printf("End\n"); break; default: printf("Invalid\n"); break; }; }while(option != 5); return 0; }
问题根源
问题确实出在printVetor函数中,你在遍历打印时直接修改了原哈希表的链表指针:
(vetoraux[n]).next = (vetoraux[n]).next -> next;
这行代码会逐步将原链表的头节点往后移动,最终会把哈希表中对应槽位的next指针置为NULL,导致第二次打印时无法找到任何数据。
修复方案
使用临时指针遍历链表,不修改原哈希表的结构:
void printVetor(no * vetor){ for (int n = 0; n <= 9; n++){ printf("槽位 %d: ", n); // 用临时指针遍历,不改动原链表 no *current = vetor[n].next; if(current == NULL){ printf("->[NULL]\n"); }else{ do{ printf("-> [id: %d] ", current->id); current = current->next; } while (current != NULL); printf("-> [NULL]\n"); } } }
额外优化建议
- 简化插入逻辑:插入函数无需分情况判断链表是否为空,直接统一头插即可:
void insert(no * vetor, int idInsert, char nameInsert, int pinsert){ no *newNo = (no*)malloc(sizeof(no)); newNo->id = idInsert; newNo->name = nameInsert; // 统一头插,逻辑更简洁 newNo->next = vetor[pinsert].next; vetor[pinsert].next = newNo; }
- 添加内存释放:避免内存泄漏,可添加哈希表销毁函数:
void freeHashTable(no * vetor){ for(int n = 0; n <=9; n++){ no *current = vetor[n].next; while(current != NULL){ no *temp = current; current = current->next; free(temp); } vetor[n].next = NULL; } }
在main函数循环结束后调用freeHashTable(vetor);即可。
内容的提问来源于stack exchange,提问作者Caio Gabriel
相关产品推荐
相关产品推荐

