题目
已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B的差集(A出现而不在B出现的元素所构成的集合),并以同样的形式存储,同时返回集合的元素个数。
题解
求A和B的交集(A出现而B不出现的元素集合),因为是递增序列。设pa和pb分别指向链表A和链表B的首元结点,我们进行比较:
- 如果 pa->data < pb->data 。说明 pa->data 不会在链表B中出现,为交集元素,加入集合,pa指针后移。
- 如果 pa->data == pb->data 。说明 pa->data 是链表A和链表B中都有的元素,不为交集元素。删除pa指针并后移。
- 如果 pa->data > pb->data 。说明 pb->data 不可能在链表A中出现,但并不能判断 pa->data 是否是交集元素,pb指针后移。
/*
已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出两个集合A和B的差集(A出现而不在B出现的元素所构成的集合),并以同样的形式存储,同时返回集合的元素个数。
*/
#include <iostream>
using namespace std;
typedef struct LNode {
int data;
struct LNode *next;
}LNode, *LinkList;
void createList(LinkList &L) {
cout << "链表的元素个数:" << endl;
int n;
cin >> n;
L = new LNode;
L->next = NULL;
cout << "链表的元素:" << endl;
LinkList p = NULL, q = L;
for (int i = 0; i < n; ++i) {
p = new LNode;
cin >> p->data;
p->next = q->next;
q->next = p;
q = p;
}
}
void printList(LinkList L) {
LinkList p = L->next;
while (p) {
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
int mergeList(LinkList &La, LinkList &Lb) {
LinkList pa = La->next;
LinkList pb = Lb->next;
LinkList pre = La, q;
int cnt = 0;
while (pa && pb) {
if (pa->data < pb->data) {
pre = pa;
pa = pa->next;
cnt++;
} else if (pa->data == pb->data) {
pre->next = pa->next;
q = pa;
pa = pa->next;
delete q;
} else {
pb = pb->next;
}
}
while (pa) {
pa = pa->next;
cnt++;
}
return cnt;
}
int main() {
LinkList La = NULL, Lb = NULL;
cout << "La链表:" << endl;
createList(La);
cout << "Lb链表:" << endl;
createList(Lb);
cout << "La链表:" << endl;
printList(La);
cout << "Lb链表:" << endl;
printList(Lb);
int elementCount = mergeList(La, Lb);
cout << "A和B的差集元素个数:" << elementCount << endl;
printList(La);
}