运用静态链表求集合运算(A-B)∪(B-A)

假设由终端输入集合元素,先建立表示集合A的静态链表S,而后在输入集合B的元素的同时查找S表,若存在和B相同的元素,则从S表中删除之,否则将此元素插入S表。
  1. 将这个数组空间初始化为一个链表 //算法2.14
  2. 从备用空间取得结点 //算法2.15
  3. 将空闲结点链接到备用链表上 //算法2.16
//算法2.14-2.17解决A∪B-A∩B 
#include <iostream>
using namespace std;

#define MAXSIZE 1000 
#define OK 1
#define ERROR 0
#define true 1
#define false 0 
#define OVERFLOW -2 

typedef int Status;     //Status 是函数类型,其值是函数结果状态返回值 
typedef int ElemType;   //Elemtype是可选择类型,这里设为int

//创建静态单链表 
typedef struct{
    ElemType data;
    int cur;
}component,SLinkList[MAXSIZE];

//创建空表
void InitSpace_SL(SLinkList &space){
    //将一维数组space中各分量链成一个备用链表,space[0]为头指针
    //'0'表示空指针
    for(int i=0;i<MAXSIZE-1;i++)space[i].cur=i+1;
    space[MAXSIZE-1].cur=0;         //尾指针指向空指针; 
} //InitSpace   算法2.14 

int New_SL(SLinkList &space){
    //若备用空间链表非空,则返回分配的结点下标,否则返回0; 
    int i=space[0].cur;             //space[0].cur相当于一个temp变量,指向的永远都是新结点,除非溢出 
    if(space[0].cur)space[0].cur=space[i].cur;           //每个结点的下标指向下一个结点;可类比于指针链表
    return i;                       //返回分配的结点下标 
}//New_SL       算法2.15 

void Free_SL(SLinkList &space,int k){
    //将下标为k的空闲结点回收到备用链表
    space[k].cur=space[0].cur;      //其结果相当于将这个结点插入到了原本接下来要插入的结点之前。 
    space[0].cur=k;                      
} //Free_SL     算法2.16 

void ListTraverse(SLinkList space,int S){//遍历静态链表 
    int k=space[S].cur;
    while(space[k].cur){
    cout<<space[k].data<<" ";
    k=space[k].cur;
    }cout<<space[k].data;
} 

void difference(SLinkList &space,int &S){
    //依次输入集合A和B的元素,在一维数组space中建立表示集合A∪B-A∩B 
    //的静态链表,S为其头指针。假设备用空间足够大,space[0].cur为其头指针
    int A,B;
    int i;                          //建立存储结点下标的变量
    InitSpace_SL(space);            //初始化备用空间
    int r;                          
    S=New_SL(space);                //将头指针赋给S
    r=S;                            //r指向S的当前最后结点 
    cout<<"请分别输入集合A与集合B元素个数:";
    cin>>A>>B;                      //输入A,B元素个数
    for(int j=0;j<A;j++)
    {   i=New_SL(space);            //分配结点下标
        cin>>space[i].data;         //输入数据
        space[r].cur=i;r=i;         //将该结点插入到表尾 
     } //建立了静态链表A

     space[r].cur=0;                //尾结点的指针为空
     for(int j=0;j<B;j++)
     {                              //依次输入B的元素,如果在A中存在,则删除,否则插入
        ElemType b; 
        int p=S;
        int k=space[S].cur;         //k指向第一个结点
        cin>>b;
        while(k!=space[r].cur&&space[k].data!=b){
            p=k;k=space[k].cur;     //类比指针链表 
        } 
        if(k==space[r].cur){        //该元素不在A中,插入在r所指结点之后,且r的位置不变
        i=New_SL(space);            //分配新的结点 
        space[i].data=b;
        space[i].cur=space[r].cur;
        space[r].cur=i;
        //r=i;                      //这时的尾指针是指原来A中的尾指针,而不是总链表的,无需添加,提高效率     
        }                           //不过这时B中元素是倒序插入的 
        else{                       //该元素已在表中,删除之 
        space[p].cur=space[k].cur;
        Free_SL(space,k); 
        if(r==k)r=p;                //若删除的是r所指结点,则需修改尾指针 
        } 
     }
}


Status main()
{
    SLinkList space;
    int S;
    difference(space,S);
    cout<<"合并后的链表为:\n";
    ListTraverse(space,S); 
    return 0;
 }

参考资料:
严蔚敏,吴伟民.数据结构(C语言版). 北京:清华大学出版社,2007

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值