集合的差集

已知集合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;
}

 

 

posted @ 2017-06-12 09:12  泡面小王子  阅读(1024)  评论(0编辑  收藏  举报