单链表交集与并集程序异常:重复值及显示问题如何解决?
链表并集与交集去重问题修复
你的C语言链表程序存在两个核心问题:
- 并集中出现重复值(比如测试用例里的两个
1) - 当原链表包含重复元素时,交集也会生成重复项
原代码问题分析
并集函数
getUnion的错误- 遍历第一个链表时直接插入所有元素,未做去重检查,若原链表本身有重复元素,结果会带重复
- 第二个循环的
if(!isPresent(result, t2->data))后面多了一个分号;,导致插入语句不受条件控制,无论元素是否已存在都会被插入
交集函数
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函数:- 遍历第一个链表时,增加
isPresent检查,仅插入结果链表中没有的元素,避免原链表自身重复导致的问题 - 移除第二个
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
相关产品推荐
相关产品推荐

