You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

字符串链表的并集与交集实现问题及创建报错排查

字符串链表并集交集实现问题:创建与插入失败的解决

我尝试编写两个字符串链表的并集和交集代码,但创建字符串链表失败,无法插入节点与显示内容,且代码仅能读取链表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){

问题分析与修复方案

核心问题点

  1. 未初始化的字符指针:main中的char *arr仅声明指针未分配内存,直接使用arr[i]会触发未定义行为;且scanf("%s", arr[i])需要传入字符串指针,但arr[i]是单个字符,类型不匹配。
  2. 字符串比较错误:isPresent函数用==比较字符串,实际对比的是指针地址而非内容,需改用strcmp。
  3. 显示格式错误:display函数用%d输出字符串指针,应改为%s输出字符串内容。
  4. 字符串内存复用:直接存入输入的字符串指针会导致所有节点指向同一块内存,后续输入会覆盖之前内容,需为每个字符串分配独立内存。
  5. 冗余代码: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 17:25:26