问题描述
已知集合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 data;
node* next;
};
请完成函数void difference(node** LA , node* LB);
分析问题
注:此题中没有规定两个链表是递增的
思路:A中的每个元素都要在B中查找是否存在,找到即删除改点
因为要删除A中的节点,所以必须要保存上一个节点,
void Difference(Node** LA, Node* LB)
{
if (LA == NULL || *LA == NULL || LB == NULL)
return;
Node *pa = *LA;
Node *pb = NULL;
Node *pre = NULL;//保存之前的节点
Node *del = NULL;//删除的节点
while (pa)
{
pb = LB;
//在LB中寻找pa节点
while (pb && pb->_value != pa->_value)
{
pb = pb->_next;
}
//跳出循环,找到或者pb为空
if (pb)//找到相同的
{
//说明是LA第一个节点要删除
if (pre == NULL)
{
*LA = pa->_next;
}
else
{
pre->_next = pa->_next;
}
//删除节点
del = pa;
pa = pa->_next;
delete del;
}
else
{
//LB遍历完,没找到相同的节点
pre = pa;
pa = pa->_next;
}
}
}
变形,求两个递增链表的差集
分析:这个问题比上一个问题更容易,因为是递增的,所以不必每次查找时都遍历另一个链表
void IncressDifference(Node** LA, Node* LB)
{
if (LA == NULL || *LA == NULL || LB == NULL)
return;
Node *pa = *LA;
Node *pb = LB;
Node *pre = NULL;//保存之前的节点
Node *del = NULL;//删除的节点
while (pa && pb)
{
if (pa->_value > pb->_value)
{
pb = pb->_next;
}
else if (pa->_value < pb->_value)
{
pa = pa->_next;
pre = pa;//保存之前的一个节点
}
else
{
//值相等删除该节点
if (pre == NULL)
{
//链表第一个节点
pa = pa->_next;
}
else
{
pre->_next = pa->_next;
}
del = pa;
delete pa;
pa = pa->_next;
}
}
}