C语言实现集合的交,并,差

C语言实现集合的交,并,差
作者:Raining_C      来源:http://blog.csdn.net/Raining_CN    

【问题描述】
        编制一个能演示执行集合的并、交和差运算的程序
【基本要求】
       (1)集合的元素限定为小写字母字符[ 'a'......'z' ]
       (2 )演示程序以用户和计算机对话的方式执行
【测试数据】

【实现提示】
          以有序链表表示集合
【代码过程】
    1。先定义 集合的数据类型 notes.h  
         

//notes.h
typedef struct LNode...{
    ElemType    data;
    LNode        *next;
}*Link, *Position;

typedef struct...{
    Link    head,tail;
    int        len;
}LinkSet;
   //~
    2。以后要用的一些常量放在   constValues.h
       #include<stdio.h>
#include <malloc.h>
#include <stdlib.h>
//函数结果状态代码
#define    TRUE    1
#define    FALSE    0
#define    OK        1
#define    ERROR    0
#define    INFEASIBLE    -1
#define OVERFLOW    -2   

#define ElemType        int        //存放数据的类型

typedef int    Status;                //函数的返回值
   //~
    3。集合实现函数   setsFun.h

/**//****************** 函数定义 *********************/
Status InitSets(LinkSet &ls)...{   
    //初始化 集合
    ls.head = (Link) malloc( sizeof(Link));
    ls.tail = (Link) malloc( sizeof(Link));   
    if(!ls.head || !ls.tail) exit(OVERFLOW);    //如果分配失败

    ls.head->next = ls.tail->next =    NULL;        //头、尾指针为空
    ls.len = 0;                                    //长度为0   
    return OK;
}

Status CreateNode(Link &link,ElemType e)...{
    //创建一节点,内容为e
    link = (Link) malloc( sizeof(Link));
    if(!link)    exit(OVERFLOW);   
    link->data = e;                                //值设定
    link->next = NULL;                            //指向空
    return OK;
}

Position PriorInsertNode(LinkSet &ls,Link &link)...{
    //找出节点link要插入到ls的前一个节点
    if(!ls.head->next) return ls.head;
    Link h1 = ls.head->next, h2 = h1->next;            //h1:前一节点,h2:前一节点的后一节点
    if(link->data < h1->data) return ls.head;        //如果比第一个节点小,返回头指针
    while(h1 && h2)...{
        if(h1->data < (link->data) && h2->data > (link->data) )    //如果>h1  && <h2,说明找到插入的地方了
            break;
        if(h1->data == (link->data) || h2->data ==(link->data) )
            return NULL;                            //如果重复,返回NULL
        else                                        //否则,顺次往后挪一个节点
            h1=h2,h2=h1->next;
    }
    return h1;
}

Status Append(LinkSet &ls, Link &link)...{
    //向集合末尾追加节点
    if(ls.head->next == NULL)    ls.head->next = link;
    else ls.tail->next->next = link;
    ls.tail->next = link;
    ls.len ++;
    return OK;
}

Status InsertNode(LinkSet &ls, Link &link)...{
    //向集合中插入节点
    Position p = PriorInsertNode(ls,link);
    if(!p)    return ERROR;                        //如果集合中已有相应元素
    link->next = p->next;
    if(!p->next)    ls.tail->next = link;        //如果前一节点为尾节点,修改tail
    p->next = link;   
    ls.len++;
    return OK;
}

Position PriorNode(LinkSet &ls, Link &link)...{
    //返回集合中 该节点的前一节点,不存在返回NULL
    int j=0;
    Link pre,h = ls.head;
    while(h->next && j<=ls.len && h!=link)...{
        pre = h; h=h->next; j++;
    }
    if(j==0)    return    NULL;
    return pre;
}

 

Status PrintSets(LinkSet &ls)...{
    //打印集合
    Link h=ls.head->next;
    printf("[ ");
    while(h)...{
        printf("%c ",h->data);
        h = h->next;
    }
    printf(" ] ");
    return OK;
}

Position GetHead(LinkSet &ls)...{
    //获得集合的头节点
    return ls.head;
}

Position NextPos(Link &link)...{
    //获得当前节点的下一个节点
    return link?link->next:link;
}

Status Empty(LinkSet &ls)...{
    //空为真
    return ls.head->next==NULL;
}

ElemType GetCurElem(Link &link)...{
    //获得当前节点的数据
    return link->data;
}

int Compare(Link &la, Link &lb)...{
    //判断两个节点的大小
    return la->data - lb->data;
}

int Compare(ElemType e1, ElemType e2)...{
    //比较两个数字的大小
    return e1-e2;   
}

Status DelFirst(LinkSet &ls,Link &q)...{
    //已知h为线性链表的头节点,删除表中的第一个节点,并以q返回
    Link h = ls.head;
    if(!h->next) return ERROR;
    q = h->next;   
    h->next = h->next->next;
    q->next=NULL;   
    ls.len--;
    return OK;
}

Status FreeNode(Link &l)...{//释放节点,有问题
    free(l);
    return OK;
}

Status UnionSets(LinkSet lsa, LinkSet &lsb, LinkSet &lsc)...{
    //已知集合ls1,ls2的元素按值非递减排列
    //将集合ls1,ls2的并集到ls3
    if( !InitSets(lsc) ) return ERROR;
    Link node;
    Link ha = lsa.head, hb=lsb.head;            //找到两节点的头指针
    Link pa = NextPos(ha), pb = NextPos(hb);
    while( !Empty(lsa) && !Empty(lsb) )...{       
        int result = Compare(pa,pb);            //比较两节点大小
        if(  result<0) ...{
            DelFirst(lsa,node);Append(lsc,node); pa = NextPos(ha);        //向lsc插入lsa的相关节点   
        }else if(result>0)...{                                                //向lsc插入lsb的相关节点
            DelFirst(lsb,node);Append(lsc,node); pb = NextPos(hb);   
        }else...{                                   
            DelFirst(lsb,node); pb = NextPos(hb);//如果两 节点相同,删除lsb中重复的节点,即以lsa为标准
        }
    }
    while(!Empty(lsa))...{           
        DelFirst(lsa,node);Append(lsc,node);
    }
    while(!Empty(lsb))...{
        DelFirst(lsb,node);Append(lsc,node);
    }
    return OK;
}

 

Status IntersectionSets(LinkSet &lsa,LinkSet &lsb, LinkSet &lsc)...{
    //已知集合ls1,ls2的元素按值非递减排列
    //将集合ls1,ls2的交集到ls3
    if( !InitSets(lsc) ) return ERROR;
    Link node;
    Link ha = lsa.head, hb=lsb.head;
    Link pa = NextPos(ha), pb = NextPos(hb);
    while( !Empty(lsa) && !Empty(lsb) )...{
        int result = Compare(pa,pb);
        if(  result<0) ...{
            DelFirst(lsa,node);pa = NextPos(ha);           
        }else if(result>0)...{
            DelFirst(lsb,node); pb = NextPos(hb);   
        }else...{
            DelFirst(lsb,node); Append(lsc,node);pb = NextPos(hb);
            DelFirst(lsa,node);pa = NextPos(ha);
        }
    }
    while(!Empty(lsa))...{
        DelFirst(lsa,node);Append(lsc,node);
    }
    return OK;
}

Status DifferenceSets(LinkSet &lsa,LinkSet &lsb, LinkSet &lsc)...{
    //已知集合ls1,ls2的元素按值非递减排列
    //ls3 = ls1 - ls2
    if( !InitSets(lsc) ) return ERROR;
    Link node;
    Link ha = lsa.head, hb=lsb.head;
    Link pa = NextPos(ha), pb = NextPos(hb);//,pb2 = NextPos(pb1);
    while( !Empty(lsa) && !Empty(lsb) )...{
        int result = Compare(pa,pb);
        if(  result<0) ...{
            DelFirst(lsa,node);Append(lsc,node);pa = NextPos(ha);           
        }else if(result>0)...{
            DelFirst(lsb,node); pb = NextPos(hb);   
        }else...{
            DelFirst(lsa,node); pa = NextPos(ha);
            DelFirst(lsb,node); pb = NextPos(hb);           
        }
    }
    return OK;
}

Status CopySets(LinkSet lsa, LinkSet lsb)...{
    //将集合lsa拷贝到lsb中
    InitSets(lsb);
    Link la = lsa.head->next, lb = lsb.head->next;
    while(la)...{
        Link node;
        CreateNode(node,la->data);
        lb=node;
        lsb.len++;

        la = la->next;
        lb = lb->next;
    }
    lsb.tail = lb;
    return OK;
}
//~    4。测试 test.cpp
#include "constValues.h"        //常量头 文件
#include "notes.h"                //节点定义 头文件
#include "setsFun.h"            //集合操作函数 头文件

/**//**************** 测试 ***********************************/
void Initialization()...{
    printf("**************************************************************************** "    );
    printf("*MakeSet1-1     MakeSet1-2  Union-u  Intersection-i  Difference-d  Quit-q * "    );
    printf("**************************************************************************** "    );
}


void main()
...{   
    LinkSet set1,set2,set3,seta,setb;
    InitSets(set1),InitSets(set2);        //初始化集合
    while(1)...{
        Initialization();               
        printf("集合Set1:");
        PrintSets(set1);                //打印集合set1
        printf("集合Set2:");
        PrintSets(set2);                //打印集合set1
        printf("请键入操作代码:");
        fflush(stdin);        //清空缓冲区
        char oper = getchar();
        char setsContent[200];
        switch(oper)
        ...{
        case '1':                        //集合set1 赋值
            printf("请输入集合Set1的内容:");
            fflush(stdin);
            gets(setsContent);           
            InitSets(set1);
            SetSets(set1,setsContent);           
            break;
        case '2':                        //集合set1 赋值
            printf("请输入集合Set1的内容:");
            fflush(stdin);
            gets(setsContent);
            InitSets(set2);
            SetSets(set2,setsContent);
            break;
        case 'u':
        case 'U':                        //求并       
            InitSets(set3);           
            CopySets(set1,seta);        //因为求并的算法是添加一个节点,删除set1,set2中对应的节点,   
            CopySets(set2,setb);        //所以要复制一份
            UnionSets(seta,setb,set3);    //下同       
            printf("set1 U set2=: ");
            PrintSets(set3);
            fflush(stdin);
            getchar();
            break;
        case 'i':
        case 'I':                        //求交   
            InitSets(set3);       
            CopySets(set1,seta);               
            CopySets(set2,setb);
            IntersectionSets(seta,setb,set3);
            printf("set1 交 set2=: ");
            PrintSets(set3);
            fflush(stdin);
            getchar();
            break;
        case 'd':
        case 'D':                        //求差
            InitSets(set3);       
            CopySets(set1,seta);           
            CopySets(set2,setb);
            DifferenceSets(seta,setb,set3);
            printf("set1 - set2=: ");
            PrintSets(set3);
            fflush(stdin);
            getchar();
            break;           
        case 'q':
        case 'Q':
            exit(0);
            break;
        }
        system("cls");    //清屏
    }
}

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值