集合的差集
已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。
链表结点的结构类型定义如下:
struct node { int elem; node* next; };
请完成函数void difference(node** LA , node* LB)
本题的解法思路较简单:
因为要求集合A和集合B的差集(A-B),结果保存在集合A中.
所以我们取出集合A中每一个元素,然后在集合B中寻找,找到即删除此节点 否则保留
此时while循环跳出只有两种情况,pb为NULL或者 pa->elem==pb->elem
当pb不为null时,即找出集合A和集合B的公有元素,此时要删除这个元素
pre(实现删除节点之后的链接)
当pre为NULL时,说明是首次找到A和B的公有元素,此时 *LA指向pa->next 所以*LA仍然是头结点
当pre不为NULL时, pre指向pa->next,顺利实现删除节点的链接
当pb为空时,找下一个集合A中的元素。
#include <iostream> #include <cstring> #include <cstdlib> using namespace std; struct Lnode { int elem; struct Lnode *next; }; void CreateList(Lnode *&L,int *array,int len) { L=new Lnode; L->elem=array[0]; L->next=NULL; Lnode *p=L; for(int i=1;i<len;i++) { Lnode *newNode = (Lnode*)malloc(sizeof(Lnode)); newNode ->elem = array[i]; newNode->next = NULL; p->next = newNode; p = newNode; } } void display(Lnode *pa) { Lnode *p=pa; while(p) { cout<<p->elem<<" "; p=p->next; } } void Difference(Lnode **LA,Lnode *LB) { if(*LA==NULL||LB==NULL) return; Lnode *pa,*pb,*pre,*q; pre=NULL; pa=*LA; while(pa) { pb=LB; while(pb&&pa->elem!=pb->elem) { pb=pb->next; } if(pb)//*pa所指向元素和pb所指向元素相等 { if(!pre) *LA=pa->next; else{ pre->next=pa->next; } q=pa;//求差集 所以删除pa节点 pa=pa->next; free(q); } else{ pre=pa; pa=pa->next; } } } int main() { int arrayA[]={5,10,20,15,25,30}; int arrayB[]={5,15,35,25}; Lnode *LA=NULL; Lnode *LB=NULL; CreateList(LA,arrayA,6); CreateList(LB,arrayB,4); display(LA); cout<<endl; display(LB); cout<<endl; Difference(&LA,LB); display(LA); //cout << "Hello world!" << endl; return 0; }
每天明白一点知识