//望大师指点一二
//作者:Ricardo.M.Tan
#include"stdafx.h"
#include"stdio.h"
#include"malloc.h"
#include"string.h"
#include<iostream>
typedefintDatatype;
typedefstructNode
{
Datatype data;
structNode *next;
}Node,*Link;
//定义两个全局的指针变量,作用类似于中转枢纽
Link gp1 =NULL;
Link gp2 =NULL;
staticLinkcreat()
{
Link H, p, q;
Datatype data;
inti = 1;
intNodeCount = 0;
printf("请输入将创建的链表的长度:");
scanf_s("%d", &NodeCount);
if(NodeCount <= 0)
{
printf("创建失败!");
returnH;
}
H = (Link)malloc(sizeof(Node));
p = H;
printf("请输入节点 %d 的存储值:", i);
scanf_s("%d", &data);
while(--NodeCount)
{
q = (Link)malloc(sizeof(Node));
p->next= q;
q->data= data;
p =q;
printf("请输入节点 %d 的存储值:", ++i);
scanf_s("%d", &data);
}
q = (Link)malloc(sizeof(Node));
p->next= q;
q->data= data;
p = q;
p->next=NULL;
return(H);
}
//求交集
Link Intersection(LinkH1,LinkH2){
Link head = (Link)malloc(sizeof(Datatype));
Link tmp=head,s;
tmp->next=NULL;
Link p1 =H1->next,p2 =H2->next;//p1,p2分别指向两张链表的第一个存储位置
while(p1!=NULL)//p1指向空结束
{
while(p2!=NULL)//p2指向空结束
{
if(p2->data == p1->data)
{
s= (Link)malloc(sizeof(Datatype));
s->data= p1->data;
s->next=NULL;
tmp->next= s;
tmp= s;
break;
}
p2=p2->next;//p2前移,循环遍历
}
p1 =p1->next;
p2 =H2->next;//重置p2的指向
}
returnhead;
}
//求并集
Link UnionSet(Linkhead1,Linkhead2)
{
Link head = (Link)malloc(sizeof(Node));
head->next=NULL;
Link tail = head;
Link InS = Intersection(head1,head2);//接收返回值
Link s, p1 =head1->next,p2 =head2->next, p3 = InS->next;
//遍历第一张链表并复制,以便接下来链接
while(p1)
{
s = (Link)malloc(sizeof(Node));
s->data= p1->data;
s->next= tail->next;
tail->next= s;
tail= s;
p1 =p1->next;
}
//接上面复制链表,将不是交集里含有的数据写入,类似链表插入
while(p2)
{
while(p3)//此循环用于遍历交集,判断p2指向的存储单元的存储值是否在交集中出现
{
if(p2->data == p3->data)
break; //终止此层循环,跳出前不会执行下一句
p3= p3->next; //条件不成立则p3指针前移
}
//若上面的执行后,p2指向的存储单元的存储值没在交集中出现,此时的p3指向NULL,若出现,p3将被重置,不写入
if(!p3) //逻辑非运算(!),即当p3=NULL时,!p3=1,为真值(true),执行语句块,反之,当p3!=NULL时,!p3=0,为假值(false),不执行语句块
{
s= (Link)malloc(sizeof(Node));
s->data= p2->data;
s->next= tail->next;
tail->next= s;
tail= s;
}
p3 =InS->next; //重置p3的指向
p2 =p2->next; //p2指针前移,循环遍历第二张链表
}
returnhead;
}
//一般输出链表
void op(Linkhead)
{
Link p;
p =head;
while(p->next !=NULL)
{
printf("%4d", p->next->data);
p =p->next;
}
}
//用于输出集合(比op()函数多了:1、空链表的判断 2、统计集合中元素个数)
void Print(Linkhead)
{
Link p =head->next;
intcount = 0;
if(p ==NULL)
{
printf("空集!\n");
return;
}
while(p)
{
printf("%3d", p->data);
count++;
p =p->next;
}
printf("(共%d个数据)\n", count);
}
//主函数入口
int main()
{
intflag = 1;
intcount=1;//用于执行控制
printf("----------------------\n提示:请先创建链表!!!\n----------------------\n");
while(flag)
{
printf("\t\t 1--创建2张新链表\n");
printf("\t\t 2--求交集\n");
printf("\t\t 3--求并集\n");
printf("\t\t 0--退出程序\n");
printf("请选择序号:");
scanf("%d", &flag);
//简单处理异常
if(flag>3){
printf("----------------------------\n警告:指令表不包含该序号!!!\n----------------------------\n");
}
else{
if(flag>count){
count= 4;
printf("----------------------------------------\n警告:还未创建链表,自动跳转到创建链表!!!\n----------------------------------------\n");
gotolable;
}
switch(flag)
{
lable:
case1:
{
printf("创建第一张链表\n");
gp1= creat();
printf("新建链表:");
op(gp1);
printf("\n");
printf("\n创建第二张链表\n");
gp2= creat();
printf("新建链表:");
op(gp2);
printf("\n\n");
}
break;
case2:
{
printf("\n交集为:");
Link InS = Intersection(gp1, gp2);
Print(InS);
printf("\n\n");
}
break;
case3:
{
printf("\n并集为:");
Link Union = UnionSet(gp1, gp2);
Print(Union);
printf("\n\n");
}
break;
case0:
break;
default:
printf("警告,错误!!!\n");
break;
}
}
}
//system("pause");
return0;
}