假设由终端输入集合元素,先建立表示集合A的静态链表S,而后在输入集合B的元素的同时查找S表,若存在和B相同的元素,则从S表中删除之,否则将此元素插入S表。
- 将这个数组空间初始化为一个链表 //算法2.14
- 从备用空间取得结点 //算法2.15
- 将空闲结点链接到备用链表上 //算法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