字符串链表的并集与交集实现问题及创建报错排查
字符串链表并集交集实现问题:创建与插入失败的解决
我尝试编写两个字符串链表的并集和交集代码,但创建字符串链表失败,无法插入节点与显示内容,且代码仅能读取链表1的字符串。附上代码及报错信息,希望了解字符串链表的正确创建方法,解决当前问题。
原代码
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct node{ char* data; struct node *next; } NODE; NODE* create(char* data){ NODE* newnode = (NODE*)malloc(sizeof(NODE)); newnode->data = data; newnode->next = NULL; return newnode; } void insertAtBeg(NODE **head, char* data){ NODE *newnode = create(data); newnode->data = data; newnode->next = (*head); (*head) = newnode; } void display(NODE *temp){ while(temp != NULL){ printf("%d->",temp->data); temp = temp->next; } } int isPresent(NODE *head, char* data){ NODE *temp = head; while(temp != NULL){ if(temp->data == data) return 1; temp = temp->next; } return 0; } NODE* getUnion(NODE* head1, NODE* head2){ NODE* result = NULL; NODE *t1 = head1; NODE *t2 = head2; while(t1 != NULL){ insertAtBeg(&result, t1->data); t1 = t1->next; } while(t2 != NULL){ if(!isPresent(result,t2->data)) insertAtBeg(&result, t2->data); t2 = t2->next; } return result; } NODE* getIntersection(NODE *head1,NODE *head2){ NODE* result = NULL; NODE *t1 = head1; while(t1 != NULL){ if(isPresent(head2,t1->data)) insertAtBeg(&result,t1->data); t1 = t1->next; } return result; } int main(){ NODE* head1 = NULL; NODE* head2 = NULL; NODE* intersection = NULL; NODE* unin = NULL; int m,n; char *arr; printf("Enter the size of the linked list1:\n"); scanf("%d",&m); printf("Enter the elements:\n"); for(int i = 0; i< m ; i++){ scanf("%s",arr[i]); insertAtBeg(&head1,arr[i]); } printf("\nDisplaying linked list1:\n"); display(head1); printf("\nEnter the size of linked list 2:\n"); scanf("%d",&n); printf("\nEnter the elements:\n"); for(int i = 0; i< n ; i++){ scanf("%s",arr[i]); insertAtBeg(&head2,arr[i]); } printf("\nDisplaying linked list2:\n"); display(head2); unin = getUnion(head1,head2); intersection = getIntersection(head1,head2); printf("\nUnion list:\n"); display(unin); printf("\nIntersection list:\n"); display(intersection); return 0; }
报错信息(翻译后)
警告:传递‘insertAtBeg’的参数2时在没有强制转换的情况下将整数转换为指针 [-Wint-conversion] 84 | insertAtBeg(&head1,arr[i]); | ~~~^~~ | | | char q.c:16:37: 附注:期望‘char *’但参数的类型为‘char’ 16 | void insertAtBeg(NODE **head, char* data){ | ~~~~~~^~~~ q.c:94:31: 警告:传递‘insertAtBeg’的参数2时在没有强制转换的情况下将整数转换为指针 [-Wint-conversion] 94 | insertAtBeg(&head2,arr[i]); | ~~~^~~ | | | char q.c:16:37: 附注:期望‘char *’但参数的类型为‘char’ 16 | void insertAtBeg(NODE **head, char* data){
问题分析与修复方案
核心问题点
- 未初始化的字符指针:
main中的char *arr仅声明指针未分配内存,直接使用arr[i]会触发未定义行为;且scanf("%s", arr[i])需要传入字符串指针,但arr[i]是单个字符,类型不匹配。 - 字符串比较错误:
isPresent函数用==比较字符串,实际对比的是指针地址而非内容,需改用strcmp。 - 显示格式错误:
display函数用%d输出字符串指针,应改为%s输出字符串内容。 - 字符串内存复用:直接存入输入的字符串指针会导致所有节点指向同一块内存,后续输入会覆盖之前内容,需为每个字符串分配独立内存。
- 冗余代码:
insertAtBeg中重复赋值newnode->data = data,create函数已完成该操作。
修复后的完整代码
#include<stdio.h> #include<stdlib.h> #include<string.h> typedef struct node{ char* data; struct node *next; } NODE; NODE* create(char* data){ NODE* newnode = (NODE*)malloc(sizeof(NODE)); // 为字符串分配独立内存并复制内容 newnode->data = strdup(data); newnode->next = NULL; return newnode; } void insertAtBeg(NODE **head, char* data){ NODE *newnode = create(data); newnode->next = (*head); (*head) = newnode; } void display(NODE *temp){ while(temp != NULL){ printf("%s->", temp->data); temp = temp->next; } printf("NULL"); } int isPresent(NODE *head, char* data){ NODE *temp = head; while(temp != NULL){ // 使用strcmp比较字符串内容 if(strcmp(temp->data, data) == 0) return 1; temp = temp->next; } return 0; } NODE* getUnion(NODE* head1, NODE* head2){ NODE* result = NULL; NODE *t1 = head1; NODE *t2 = head2; while(t1 != NULL){ if(!isPresent(result, t1->data)) // 避免重复插入 insertAtBeg(&result, t1->data); t1 = t1->next; } while(t2 != NULL){ if(!isPresent(result, t2->data)) insertAtBeg(&result, t2->data); t2 = t2->next; } return result; } NODE* getIntersection(NODE *head1,NODE *head2){ NODE* result = NULL; NODE *t1 = head1; while(t1 != NULL){ if(isPresent(head2, t1->data) && !isPresent(result, t1->data)) // 避免重复插入 insertAtBeg(&result, t1->data); t1 = t1->next; } return result; } // 释放链表内存,避免内存泄漏 void freeList(NODE* head){ NODE* temp; while(head != NULL){ temp = head; head = head->next; free(temp->data); free(temp); } } int main(){ NODE* head1 = NULL; NODE* head2 = NULL; NODE* intersection = NULL; NODE* unin = NULL; int m,n; // 定义固定长度数组存储临时输入,假设单字符串最长100字符 char arr[100]; printf("输入链表1的大小:\n"); scanf("%d",&m); printf("输入元素:\n"); getchar(); // 处理scanf后的换行符 for(int i = 0; i< m ; i++){ fgets(arr, sizeof(arr), stdin); arr[strcspn(arr, "\n")] = '\0'; // 去掉fgets读取的换行符 insertAtBeg(&head1, arr); } printf("\n链表1内容:\n"); display(head1); printf("\n\n输入链表2的大小:\n"); scanf("%d",&n); printf("输入元素:\n"); getchar(); for(int i = 0; i< n ; i++){ fgets(arr, sizeof(arr), stdin); arr[strcspn(arr, "\n")] = '\0'; insertAtBeg(&head2, arr); } printf("\n链表2内容:\n"); display(head2); unin = getUnion(head1,head2); intersection = getIntersection(head1,head2); printf("\n\n并集链表:\n"); display(unin); printf("\n\n交集链表:\n"); display(intersection); // 释放内存 freeList(head1); freeList(head2); freeList(unin); freeList(intersection); return 0; }
修复说明
- 输入处理:改用
fgets读取字符串,避免scanf的空格截断问题;用strcspn去除换行符,使用固定长度数组存储临时输入,规避未初始化指针风险。 - 字符串存储:用
strdup为每个节点的字符串分配独立内存,确保内容不会被后续输入覆盖。 - 字符串比较:替换
==为strcmp,正确对比字符串内容。 - 显示优化:将
%d改为%s,并在链表末尾添加NULL标识结束。 - 去重处理:在并集、交集函数中添加重复检查,避免结果链表出现重复元素。
- 内存管理:新增
freeList函数释放链表内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者dev0419
相关产品推荐
相关产品推荐

