已知集合A和B的元素分别用不含头结点的单链表存储, 求解集合A与B的差集,并将结果保存在集合A的单链表中

1.【附加题】–已知集合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);

#include<iostream>
using namespace std;
typedef struct Node
{
   int elem;
   Node* next;
   Node(const int x)
       :elem(x)
       ,next(NULL)
   {}
}Node;
void difference(Node*& LA,Node*& LB)
{
    //1.两个链表有一个为空,不用求差集
    if (LA==NULL||LB==NULL)
    {
        return;
    }
    //2.两个链表都不为为空
    else
    {
        Node* cur=LA;
        Node* cur1=LB;
        Node* del=NULL;
        Node* delnext=NULL;
        Node* prev=NULL;
        while (cur&&cur1)
        {
            while(cur1)
            {
                if (cur->elem==cur1->elem)
                {
                    if (cur->next==NULL)
                    {
                        del=cur;
                        cur=NULL;
                        //删除只有一个结点的链表的第一个结点
                        if (prev==NULL)
                        {
                            LA=NULL;
                        }
                        else
                        {
                            prev->next=NULL;
                        }
                    }
                    else 
                    {
                        del=cur->next;
                        delnext=del->next;
                        std::swap(cur->elem,del->elem);
                        cur->next=delnext;  
                    }
                    break;
                }
                cur1=cur1->next;
            }
            prev=cur;
            if (del!=NULL)
            {
                delete del;
                del=NULL;
            }
            else
            {

               cur=cur->next;
            }
            cur1=LB;
        }
    }

}
Node* CreatLinkList(int* arr,int sz)
{
    Node* PHead=new Node(arr[0]);
    Node* cur=PHead;
    for (int i=1;i<sz;i++)
    {
       cur->next=new Node(arr[i]);
       cur=cur->next;
    }
    return PHead;
}
void Printf(Node* LA)
{
    if (LA==NULL)
    {
        return;
    }
    else
    {
        Node* cur=LA;
        while (cur)
        {
            cout<<cur->elem<<"->";
            cur=cur->next;
        }
    }

}
int main()
{
    int A[]={5,10,20,15,25,30,66,99,23,77};
    int B[]={5,15,35,25,77,65,54,66};
    int sz1=sizeof(A)/sizeof(A[0]);
    int sz2=sizeof(B)/sizeof(B[0]);
    Node* LA=CreatLinkList(A,sz1);
    Node* LB=CreatLinkList(B,sz2);
    difference(LA,LB);
    Printf(LA);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用双指针的方法,从头结点开始遍历两个链表,比较当前节点的值大小,如果A链表当前节点的值小于B链表当前节点的值,则将A链表的指针向后移动一位,否则将B链表的指针向后移动一位。如果两个节点的值相等,则将A链表的指针向后移动一位,B链表的指针向后移动一位。直到遍历完两个链表为止,最后得到的链表C即为A,B的差集。 以下是示例代码: ``` ListNode* getDifference(ListNode* A, ListNode* B) { ListNode* C = new ListNode(0); // 创建头结点 ListNode* p = C; ListNode* pa = A->next; ListNode* pb = B->next; while (pa != nullptr && pb != nullptr) { if (pa->val < pb->val) { p->next = new ListNode(pa->val); pa = pa->next; } else if (pa->val > pb->val) { pb = pb->next; } else { pa = pa->next; pb = pb->next; } p = p->next; } while (pa != nullptr) { p->next = new ListNode(pa->val); pa = pa->next; p = p->next; } return C; } ``` ### 回答2: 算法步骤如下: 1. 创建一个新的链表C,用于存储A和B的差集。 2. 初始化指针p和q,分别指向链表A和B的头结点。 3. 判断p和q是否都到达链表尾部,若是,则结束循环;若否,则执行下一步。 4. 判断p和q所指向的节点的值的大小关系: - 若p所指向的节点的值小于q所指向的节点的值,说明p所指向的节点在B不存在,将该节点插入到链表C的尾部,并将p指针移到下一个节点,即p = p.next。 - 若p所指向的节点的值等于q所指向的节点的值,说明p所指向的节点在B存在,将p指针移到下一个节点,即p = p.next。 - 若p所指向的节点的值大于q所指向的节点的值,说明q所指向的节点在A不存在,将q指针移到下一个节点,即q = q.next。 5. 循环结束后,链表C存储的即为A和B的差集算法的时间复杂度为O(n+m),其n和m分别为链表A和B的长度。 ### 回答3: 算法如下: 1. 初始化链表C为空链表。 2. 遍历链表A和链表B,比较元素值大小,同时遍历两个链表。 3. 若链表A的当前元素值小于链表B的当前元素值,则将链表A的当前元素插入链表C的末尾,并将链表A的指针向后移动一位。 4. 若链表A的当前元素值大于链表B的当前元素值,则将链表B的当前元素插入链表C的末尾,并将链表B的指针向后移动一位。 5. 若链表A的当前元素值等于链表B的当前元素值,则将链表A和链表B的指针都向后移动一位,跳过相同的元素。 6. 当其一个链表遍历完时,将另一个链表剩余的元素依次插入链表C的末尾。 7. 返回链表C。 该算法的时间复杂度为O(max(m,n)),其m和n分别为链表A和链表B的长度。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值