链表求交集与并集

//望大师指点一二

//作者: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;

}

猜你喜欢

转载自blog.csdn.net/ricardomtan/article/details/68215581