题目描述:
已知集合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 <assert.h>
void difference(node **LA, node *LB) //注意,LA是二级指针,因为有可能修改链表头结点指向。
{
assert(nullptr != LA);
assert(nullptr != *LA);
assert(nullptr != LB);
node *pPre = nullptr; //指向pa先驱节点
node *pa = *LA; //指向LA中的节点
node *pb = LB; //指向LB中的节点
node *pTemp = nullptr; //临时指针
//循环LA中的节点,每次都在LB中寻找
while (pa)
{
pb = LB; //每次循环重新赋值,从LB头开始,遍历LB
while (pb && (pa->elem != pb->elem))
pb = pb->next;
if (pb) //说明找到了。(注意:此处不能用pa->elem == pb->elempb作为判定条件,因为只要pb不为空,才有可能比较)
{
//此时pb->elem == pb->elem,找到了两个链表中值相同的节点,进行删除操作
//判断删除的是否是LA的头结点
if (nullptr == pPre) //直接对LA进行操作,修改链表头指向(注意LA是二级指针)
*LA = pa->next;
else //不是头结点
pPre->next = pa->next;
pTemp = pa;
pa = pa->next; //更新pa
delete pTemp;
pTemp = nullptr;
}
else //遍历完LB,还是没有找到与pa->elem相同的节点。
{
pPre = pa; //更新前驱节点
pa = pa->next; //更新pa
}
}
}