求两个单链表的差集和并集

来源:互联网 发布:androidndkr10e mac 编辑:程序博客网 时间:2024/06/09 02:46

题目:-
已知集合A和B的元素分别用不含头结点的单链表存储,函数difference()用于求解集合A与B的差集,并将结果保存在集合A的单链表中。例如,若集合A={5,10,20,15,25,30},集合B={5,15,35,25},完成计算后A={10,20,30}。
这里写图片描述
思路:指针的指针pa遍历链表A,指针pb遍历链表B,当节点的值相等,删除,提前将删除位置的下一个节点保存,然后
继续遍历这两个链表直到全部遍历完后,剩下的节点连接起来就是这两个链表的差集
验证:

#include<iostream>#include<assert.h>using namespace std;struct Node{    int _data;    Node*next;    Node(int data)        :_data(data)        , next(NULL)    {}};void Different(Node**A, Node*B){    Node*pa = *A;//用来遍历A链表    //Node*pb = B;//用来遍历B链表    Node *prev = NULL;//用来保存删除后节点能连接起来    Node*del;//待删除的节点    while (pa)    {        Node*pb = B;        while (pb&&pa->_data != pb->_data)            pb = pb->next;//        if (pb)//两个节点的值相等        {            if (!prev)            {                *A = pa->next;//指向下一个节点            }            else//第一个节点相等            {                prev->next = pa->next;//指向相等节点的后一个            }            del = pa;//删除的节点            pa = pa->next;            delete del;        }        //此时链表B已经遍历完了        else        {            //更新节点的位置            prev = pa;            pa = pa->next;        }    }}void Printf(Node*root){    Node*cur = root;    while(cur)    {        cout << cur->_data << " ";        cur = cur->next;    }    cout << endl;}void Test(){    Node*n1 = new Node(5);    Node*n2 = new Node(10);    Node*n3 = new Node(20);    Node*n4 = new Node(15);    Node*n5 = new Node(25);    Node*n6 = new Node(30);    n1->next = n2;    n2->next = n3;    n3->next = n4;    n4->next = n5;    n5->next = n6;    cout << "链表A" << endl;    Printf(n1);    Node*n11 = new Node(5);    Node*n22 = new Node(15);    Node*n33 = new Node(35);    Node*n44 = new Node(25);    n11->next = n22;    n22->next = n33;    n22->next = n33;    n33->next = n44;    cout << "链表B" << endl;    Printf(n11);    cout << "链表的差集" << endl;    Different(&n1, n11);    Printf(n1);}int main(){    Test();    system("pause");    return 0;}

这里写图片描述
求交集
同样的方法,我们可以求两个单链表的交集
思路:当链表A的值小于链表B的值,链表A相后移,如果链表A的值大于链表B的值,链表B的值向后移,否则同时移,当遍历完这个链表,交集就出来了.
验证

void UnionSet(Node*L1, Node*L2){    while(L1&&L2)    {        if (L1->_data < L2->_data)        {            L1 = L1->next;        }        else if (L1->_data>L2->_data)        {            L2 = L2->next;        }        else        {            L1 = L1->next;            L2 = L2->next;        }    }}void Printf(Node*root){    Node*cur = root;    while(cur)    {        cout << cur->_data << " ";        cur = cur->next;    }    cout << endl;}void Test(){    Node*n1 = new Node(5);    Node*n2 = new Node(10);    Node*n3 = new Node(20);    Node*n4 = new Node(15);    Node*n5 = new Node(25);    Node*n6 = new Node(30);    n1->next = n2;    n2->next = n3;    n3->next = n4;    n4->next = n5;    n5->next = n6;    cout << "链表A" << endl;    Printf(n1);    Node*n11 = new Node(5);    Node*n22 = new Node(15);    Node*n33 = new Node(35);    Node*n44 = new Node(25);    n11->next = n22;    n22->next = n33;    n22->next = n33;    n33->next = n44;    cout << "链表B" << endl;    Printf(n11);    cout << "链表的交集" << endl;    UnionSet(n1, n11);    Printf(n1);}int main(){    Test();    system("pause");    return 0;}
原创粉丝点击