(3)已知两个链表A和B分别表示两个集合,其元素递增排列。请设计算法求出A与B的交集,并存放于A链表中。
[题目分析]
只有同时出现在两集合中的元素才出现在结果表中,合并后的新表使用头指针Lc指向。pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点,从第一个结点开始进行比较,当两个链表La和Lb均为到达表尾结点时,如果两个表中相等的元素时,摘取La表中的元素,删除Lb表中的元素;如果其中一个表中的元素较小时,删除此表中较小的元素,此表的工作指针后移。当链表La和Lb有一个到达表尾结点,为空时,依次删除另一个非空表中的所有元素。
#include <iostream>
using namespace std;
//定义存储
typedef struct LNode
{
int date;
struct LNode *next;
} Lnode, *Linklist;
//链表初始化
void init(Linklist &L)
{
L = new Lnode; // 开辟空间
L->next = NULL; //头节点置为空
}
//输出数据
void output(Linklist T)
{
Linklist p = T;
p = p->next;
while (p)
{
cout << p->date;
p = p->next;
}
}
//后插法构建链表
void CreateLiklist(Linklist &L, int n)
{
Linklist r = L;
for (int i = 0; i < n; i++)
{
Linklist p = new Lnode; //开辟空间,p为节点
printf("请输入%d个数据\n", i + 1);
cin >> p->date;
p->next = NULL;
r->next = p; //将新节点插入r之后
r = p; ////r指向新的尾节点
}
}
//**算法设计
void Jiaoji(Linklist &La, Linklist &Lb, Linklist &Lc)
{ //pa和pb分别是链表La和Lb的工作指针,初始化为相应链表的第一个结点
Linklist pa = La->next;
Linklist pb = Lb->next;
Linklist pc;
Lc = pc = La;//用La的头结点作为Lc的头结点
Linklist u; //用于删除节点
while (pa && pb)
{
if (pa->date == pb->date)
{
pc->next = pa;
pc = pa;
pa = pa->next;
//删除节点
u = pb;
pb = pb->next;
delete u;
}
else if (pa->date < pb->date)
{
u = pa;
pa = pa->next;
delete u;
}
else
{
u = pb;
pb = pb->next;
delete u;
}
}
while (pa)
{
u = pa;
pa = pa->next;
delete u;
}
while (pb)
{
u = pb;
pb = pb->next;
delete u;
}
pc->next = NULL; //尾节点置为空
delete Lb; //释放Lb的头节点
}
int main()
{
Linklist La, Lb, Lc;
//初始化
init(La);
init(Lb);
int n1, n2;
cout << "请输入请输入每条链表的个数";
scanf("%d %d", &n1, &n2);
//构建链表
CreateLiklist(La, n1);
CreateLiklist(Lb, n2);
//开始
Jiaoji(La, Lb, Lc);
//输出
output(Lc);
}
运行结果: