///线性表达的静态单链表存储结构
///
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
#define MAXSIZE 1000 ///链表的最大长度
typedef struct
{
int data;
int cur;
}compnent, SLinkList[MAXSIZE];
int LocateElem_SL(SLinkList S,int e){
///在静态单链线性表L中查找第1个值为e的元素
///若找到。则返回它在L中的位序,否则返回0
int i = S[0].cur; ///i指示表中第一个节点
while(i && S[i].data != e) i = S[i].cur;
return i;
}///LocateElem_SL
void InitElem_SL(SLinkList &S,int n){
///将静态单链表S初始化,使得每个指针域指向下一个节点,S[0].cur为头指针
///“0”表示空指针
///结果是该静态单链表里有n-1个节点,还有一个头节点
for(int i=0;i < n - 1; ++i) S[i].cur = i + 1;
S[n - 1].cur = 0;
}///InitElem_SL
void Scanf_SL(SLinkList &S)
{
///向静态链表输入值,输入为n-1个值
int i = S[0].cur;
while(i){
scanf("%d", &S[i].data);
i = S[i].cur;
}
}///Scanf_SL
void Printf_SL(SLinkList S,int n)
{
///输出静态单链表L
int i = S[n].cur; ///i指示表中第一个结点
printf("当前该静态单链表值为:");
while(i)
{
printf("%d ",S[i].data);
i = S[i].cur;
}
printf("\n");
}///Printf_SL
void InitSpace_SL(SLinkList &space){
///将一维数组space中各分量链成一个备用链表,space[0].cur为头指针
///“0”表示空指针
for(int i=0;i < MAXSIZE - 1; ++i) space[i].cur = i + 1;
space[MAXSIZE - 1].cur = 0;
}//InitSpace_SL
int Malloc_SL(SLinkList &space)
{
///若备用空间链表非空,则返回分配的结点下标,否则返回0
int i = space[0].cur;
if(space[0].cur) space[0].cur = space[i].cur;
return i;
}///Malloc_SL
void Free_SL(SLinkList &space, int k)
{
///将下标为k的空闲节点回收到备用链表
space[k].cur = space[0].cur; space[0].cur = k;
}
void difference(SLinkList &space, int &S){
///依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)并(B-A)
///的静态链表,S为其头指针,假设备用空间足够大,space[0].cur为其头指针
InitSpace_SL(space); ///初始化备用空间
S = Malloc_SL(space); ///生成S的头节点
int r = S; ///r指向S的当前最后节点
printf("请分别输入A和B元素的个数:");
int m,n;
scanf("%d%d",&m,&n);
printf("请输入%d个A的节点值:",m);
for(int j=1;j<=m;j++){ ///建立新集合A的链表
int i = Malloc_SL(space); ///分配节点
scanf("%d",&space[i].data); ///输入A的元素值
space[r].cur = i; r = i; ///插入到表尾
}///for
space[r].cur = 0;
printf("请输入%d个B的节点值:",n);
///依次输入B的元素,若不在当前表中,则插入,否则删除
for(int j=1; j<=n ; ++j){
int b, p = S, k = space[S].cur; ///k指向A中的第一个节点
scanf("%d", &b);
while(k != space[r].cur && space[k].data != b){ ///在当前表中查找
p = k; k = space[k].cur;
}///while///p保留是是k的上一个节点指针
if(k == space[r].cur){ ///当前表中不存在该元素,插入r所z指节点之后,且r的位置不变
int i = Malloc_SL(space);
space[i].data = b;
space[i].cur = space[r].cur;
space[r].cur = i;
/// r = i;
///这里为什么r的位置不变呢?不应该r = i吗?
///这里我加上了r = i,之后插入元素就是从尾部一个一个插
///如果不加的话,插入就是每次都从A元素的尾部插入
///对于集合来讲,顺序也许没有用
///想明白了:这里去掉了r=i,是因为题目是集合,所以没必要再去比较后进来的B的元素
}///if
else{ ///该元素已在表中,删除之
space[p].cur = space[k].cur;
Free_SL(space, k);
if(r == k) r = p; /// 若删除的是r所指的节点,则需修改尾指针
}///else
}///for
}///diffrerence
int main()
{
compnent S[MAXSIZE];
printf("请输入静态的个数n:");
int n;
scanf("%d",&n);
InitElem_SL(S,n);
Scanf_SL(S);
Printf_SL(S,0);
printf("\n");
///测试LocateElem_SL查找元素e的函数
int e,i;
printf("请输入想要查找的值:");
scanf("%d",&e);
if( i = LocateElem_SL(S,e) ) printf("该值%d在静态单链表中的位序是%d\n",e,i);
else printf("该静态单链表中没有%d\n",e);
printf("\n");
///测试difference
SLinkList space;
InitSpace_SL(space);
int s;
difference(space, s);
Printf_SL(space,s);
return 0;
}