集合的交、并、差的实现

【问题描述】
        编制一个能演示执行集合的并、交和差运算的程序
【基本要求】
       (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");    //清屏
    }

}

//~
collected by barenx
 

Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2234235

 
部分功能代码: void CMy1Dlg::OnButton1() //--------并操作 { UpdateData(true); m_C=""; UpdateData(false); Linklist l; Initlist(l); int i=0,j=0; int k=0; while(i<m_A.GetLength()) {if(m_A[i]>='a'&&m_A[i]<='z') {k=get(l,m_A[i]); if(k!=-1) Insert(l,m_A[i],k); } i++; } while(j<m_B.GetLength()) {if(m_B[j]>='a'&&m_B[j]<='z') {k=get(l,m_B[j]); if(k!=-1) Insert(l,m_B[j],k); } j++; } fuzhi(l); //Insert(l,m_A[0],1); //测试用 //Insert(l,m_A[1],2); //k=get(l,'d'); //int d=k; //m_D=k; //fuzhi(l); //UpdateData(false); } void CMy1Dlg::OnButton2() //-----------操作 {UpdateData(true); m_C=""; UpdateData(false); int i,j,k; Linklist l; Initlist( l); for(i=0;i<m_A.GetLength();i++) for(j=0;j<m_B.GetLength();j++) if(m_A[i]==m_B[j]) {k=get(l,m_A[i]); if(k!=-1) Insert(l,m_A[i],k); } fuzhi(l); UpdateData(false); } void CMy1Dlg::OnButton3() //-------------非操作 {UpdateData(true); m_C=""; UpdateData(false); Linklist l; Initlist(l); int i,j,k=0,same; for(i=0;i<m_A.GetLength();i++) {for(j=0;j<m_B.GetLength();j++) {if(m_A[i]==m_B[j]) {same=1;break;} else same=0; } if(same==0&&m_A[i]>='a'&&m_A[i]<='z') {Insert(l,m_A[i],k); k++;} } fuzhi(l); } void CMy1Dlg::OnButton4() //-----------clean操作 { clean(); } status CMy1Dlg::Initlist(Linklist &l) {l=NULL; l=(Linklist)malloc(sizeof(LNode)); if(!l) return false; l->next=NULL; return true; } void CMy1Dlg::Insert(Linklist &l,char m,int i) {Linklist q=NULL,p=NULL; Initlist(p); if(!l->next) {l->next=p;p->data=m;} else { q=l; for(int j=0;j<(i-1);j++) q=q->next; p->data=m;p->next=q->next;q->next=p; } } int CMy1Dlg::get(Linklist &l,int m) {int i=0; LNode *h=NULL; h=l->next; if(!h) return 0; //标记如L为空 for(i=1;h->data<m;) {i++;h=h->next; if(!h) return i;} if(h->data==m) return -1; //标记如果找到相同项 else return i; //否则,标记返回值为小于m的最后一个位置; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值