问题描述 :
输入A、B、C、D四个集合(集合中无重复元素,且元素值都大于0),分别存储在不带头结点的链表中。
本程序先将四个集合执行以下操作:
1.对A、B、C、D分别进行升序排序;(该功能已实现,见函数sort)。
2.做A=A+B操作:先执行两个有序链表A和B的合并,并仍然保持有序,结果存储在A中,然后删除重复元素;(该功能已实现,见函数merge和purge)。
3.做A=A-C操作:将C中出现的元素从A中删除;(该功能已实现,见函数subtract)。
4.对D中出现的元素,逐一到A中查询:
如果在A中存在,则从A中删除
如果在A中不存在,则将元素添加到A中,并保持链表A有序。
请编写函数fun的函数体实现本功能。
5.输出集合A中的元素。(该功能已实现,见函数displayLink)。
需要编写的函数的原型如下:
struct student* fun(struct student* L1, struct student* L2)
形参:
L1:传入的第一个集合,程序中将传入A集合的链表头指针
L2:传入的第二个集合,程序中将传入D集合的链表头指针
返回值:
返回第一个集合的链表的头指针
程序部分代码如下:
#include <iostream>
using namespace std;
struct student
{
int num;
student *next;
};
//从键盘读入数据创建链表,新结点插入到尾部
student *createByTail()
{
student *head;
student *p1,*p2;
int n;
n=0;
p1 = new student;
//p2 = new student;
cin>>p1->num;
head=NULL; //首先置链表为空链表
while(p1->num!=-1) //num为-1,意味着用户输入结束
{
n=n+1;
if(n==1) //创建第一个结点
head=p1;
else
p2->next=p1;
p2=p1; //p2始终指向最后一个结点(即尾指针)
p1 = new student;;//p1指向新结点
cin>>p1->num;
}
p2->next=NULL; //最后一个结点的next赋值为NULL
return head;
}
//输出链表中的信息(num)
void displayLink(struct student *head)
{
student *p;
p=head;
cout<<"head-->";
while(p!= NULL)
{
cout<<p->num<<"-->";
p=p->next;
}
cout<<"tail"<<endl;
}
//将一个节点插入链表中并使链表仍然有序
student *insertNodeInOrder(student *head,student *stu) {
student *p0,*p1,*p2;
p1 = head;
p0 = stu;
//空链表
if(head == NULL) {
p0->next = head;
head = p0;
}
else {
//查找插入位置,p2指向p1的前驱
while(p0->num > p1->num && p1->next != NULL) {
p2 = p1;
p1 = p1->next;
}
//如果上面的while循环是因第一个条件退出的,则将p0插到p2后面
if(p0->num <= p1->num) {
if(p1 == head) {
head = p0;
}
else {
p2->next = p0;
}
p0->next = p1;
}
//while循环是因p1->next == NULL结束的,说明p0->num比当前链表所有链表节点的值都要大
else {
p1->next = p0;
p0->next = NULL;
}
}
return head;
}
//对链表进行升序排序
student *sort(student *head) {
student *p = head,*node;
head = NULL; //将链表置为空
while(p) {
node = p;
p = p->next;
head = insertNodeInOrder(head,s);
}
return head;
}
//合并两个有序链表,使之任然有序
student *merge(student *La,student *Lb) {
student *pb,*node;
pb = Lb;
while(pb) {
node = pb;
pb = pb->next;
La = insertNodeInOrder(La,node);
}
return La;
}
//删除一个有序链表中重复值的节点
void purge(student *head) {
student *p,*q;
//空链表或者只有一个节点的链表直接返回
if(head == NULL || head->next == NULL) {
return;
}
p = head;
while(p->next) {
//相邻两个节点的值相等,删除后一个节点
if(p->num == p->next->num) {
q = p->next;
p->next = q->next;
delete q;
}
else {
p = p->next;
}
}
}
//做A=A-C操作:将C中出现的元素从A中删除
student *subtract(student *La,student *Lb) {
student *pa,*pb = Lb;
student *pre = NUll; //pre指向pa的前驱
while(pb) {
pa = La;
while(pa != NULL && pa->num != pb->num) {
pre = pa;
pa = pa->next;
}
if(pa != NULL) {
//在A中找到了与当前B中相等的元素
if(pa == La) {
//要删除的是头节点
La = La->next;
delete pa;
}
else {
pre->next = pa->next;
delete pa;
}
}
pb = pb->next;
}
return La;
}
/*
对D中出现的元素,逐一到A中查询:
如果在A中存在,则从A中删除
如果在A中不存在,则将元素添加到A中,并保持链表A有序。
*/
student *fun(student *L1,student *L2) {
struct student *p1,*p2 = L2;
struct student *pre = NULL; //pre为p1的前驱
while(p2) {
p1 = L1;
while(p1 != NULL && p1->num != p2->num) {
pre = p1;
p1 = p1->next;
}
if(p1 == NULL) {
//L1中没有这个元素
student *node = new student;
node->num = p2->num;
L1 = insertNodeInOrder(L1,node);
}
else {
if(p1 == L1) {
//要删除的元素为L1的头节点
L1 = L1->next;
}
else {
pre->next = p1->next;
}
delete p1;
}
p2 = p2->next;
}
return L1;
}
int main()
{
struct student *headA, *headB, *headC, *headD;
int i=0,n;
cin>>n;
while( i<n)
{
headA=createByTail();//创建链表A
headB=createByTail();//创建链表B
headC=createByTail();//创建链表C
headD=createByTail();//创建链表D
headA = sort(headA);//链表A排序
headB = sort(headB);//链表B排序
headC = sort(headC);//链表C排序
headD = sort(headD);//链表D排序
headA = merge(headA, headB);//将链表B合并到链表A中
purge(headA);//删除链表A中重复元素
headA = subtract(headA, headC);//从链表A中减去链表C中元素
headA=fun(headA, headD);//对链表A和链表D调用fun函数
displayLink(headA);//输出链表A中的元素
i++;
}
return 0;
}
输入说明 :
首先输入一行,包含一个整数N,表示共测试N组数据。
后面接着输入4*N行,每行为一个集合的元素。
每组数据的第1行为集合A的元素,第2行为集合B的元素,第3行为集合C的元素,第4行为集合D的元素。
每个集合的元素值都为大于0的整数,输入时,-1表示结束。
输出说明 :
输出的信息以head开头,以tail结尾,以“–>”分隔。如果是空链表,则直接输出“head–>tail”。具体见输出范例。
输入范例 :
2
3 5 8 10 15 9 -1
2 5 8 11 14 -1
2 5 10 -1
3 1 9 -1
3 5 8 10 15 9 -1
2 5 8 11 14 -1
2 5 10 -1
2 3 8 -1
输出范例 :
head–>1–>8–>11–>14–>15–>tail
head–>2–>9–>11–>14–>15–>tail