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

单链表交集与并集程序异常:重复值及显示问题如何解决?

链表并集与交集去重问题修复

你的C语言链表程序存在两个核心问题:

  • 并集中出现重复值(比如测试用例里的两个1)
  • 当原链表包含重复元素时,交集也会生成重复项

原代码问题分析

  1. 并集函数getUnion的错误

    • 遍历第一个链表时直接插入所有元素,未做去重检查,若原链表本身有重复元素,结果会带重复
    • 第二个循环的if(!isPresent(result, t2->data))后面多了一个分号;,导致插入语句不受条件控制,无论元素是否已存在都会被插入
  2. 交集函数getIntersection的缺陷

    • 仅检查元素是否存在于第二个链表,未检查结果链表中是否已存在该元素,若第一个链表有重复的交集元素,会重复插入

修复后的完整代码

#include<stdio.h>
#include<stdlib.h>

typedef struct node{
    int data;
    struct node *next;
} node;

void insertAtBeg(node **head, int ele){
    node *newnode = (node*)malloc(sizeof(node));
    newnode->data = ele;
    newnode->next = (*head);
    (*head) = newnode;
}

int isPresent(node *temp, int ele){
    node *t = temp;
    while(t != NULL){
        if(t->data == ele)
            return 1;
        t = t->next;
    }
    return 0;
}

void printList(node *n){
    while(n != NULL){
        printf("%d->",n->data);
        n = n->next;
    }
}

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;
}

int main(){
    node *intersection = NULL;
    node *unin = NULL;
    node *List1;
    node *List2;
    List1 = List2 = NULL;
    int i,n,m,temp;
    
    printf("Enter the size of the first linked list:\n");
    scanf("%d",&n);
    printf("Enter %d elements\n",n);
    for(i = 0;i < n;i++){
        scanf("%d",&temp);
        insertAtBeg(&List1,temp);
    }
     printf("Displaying list 1:\n");
     printList(List1);

    printf("\nEnter the size of the second linked list:\n");
    scanf("%d",&m);
    printf("Enter %d elements\n",m);
    for(i = 0;i < m;i++){
        scanf("%d",&temp);
        insertAtBeg(&List2,temp);
    }
    printf("Displaying list 2:\n");
    printList(List2);

    unin = getUnion(List1,List2);
    intersection = getIntersection(List1,List2);

    printf("\nLinked List with Union of List1 and List2:\n");
    printList(unin);
    printf("\nLinked List with Intersection of List1 and List2:\n");
    printList(intersection);
    return 0;
}

关键修改说明

  • getUnion函数:

    1. 遍历第一个链表时,增加isPresent检查,仅插入结果链表中没有的元素,避免原链表自身重复导致的问题
    2. 移除第二个if语句后的多余分号,确保条件判断生效,只插入结果链表中不存在的新元素
  • getIntersection函数:
    在判断条件中新增!isPresent(result, t1->data),确保同一个交集元素只会被插入一次,即使原链表中有重复的该元素


测试验证

用你提供的测试用例运行修复后的代码,输出会变为:

Enter the size of the first linked list:
4
Enter 4 elements
3 4 6 1
Displaying list 1:
1->6->4->3->
Enter the size of the second linked list:
4
Enter 4 elements
8 9 10 1
Displaying list 2:
1->10->9->8->

Linked List with Union of List1 and List2:
8->9->10->1->3->4->6->
Linked List with Intersection of List1 and List2:
1->

若测试原链表含重复元素的场景(比如List1输入1 1 2 2,List2输入2 2 3 3),交集会输出2->而非2->2->,并集输出3->2->1->,完全符合去重需求。

内容的提问来源于stack exchange,提问作者dev0419

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:15:32