代码
page43
数据结构-- 严蔚敏 – 第1版
/* c1.h (程序名) */
#include<string.h>
#include<ctype.h>
#include<malloc.h> /* malloc()等 */
#include<limits.h> /* INT_MAX等 */
#include<stdio.h> /* EOF(=^Z或F6),NULL */
#include<stdlib.h> /* atoi() */
#include <sys/io.h> /* eof() */
#include<math.h> /* floor(),ceil(),abs() */
#include<pthread.h> /* exit() */
/* 函数结果状态代码 */
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
/* #define OVERFLOW -2 因为在math.h中已定义OVERFLOW的值为3,故去掉此行 */
typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
#if 0
请输入集合A和B的元素个数m,n:6,4
请输入集合A的元素(共6个):cbegfd
请输入集合B的元素(共4个):abnf
c e g d n a
#endif
#define N 2
typedef char ElemType;
/* c2-3.h 线性表的静态单链表存储结构 */
#define MAXSIZE 12 /* 链表的最大长度 */
typedef struct
{
ElemType data;
int cur;
}component,SLinkList[MAXSIZE];
/* bo2-3.c 实现算法2.15、2.16的程序 (数据结构由c2-3.h定义) (3个) */
int Malloc(SLinkList space) /* 算法2.15 */
{ /* 若备用链表非空,则返回分配的结点下标(备用链表的第一个结点),否则返回0 */
int i=space[0].cur;
if(i) /* 备用链表非空 */
space[0].cur=space[i].cur; /* 备用链表的头结点指向原备用链表的第二个结点 */
return i; /* 返回新开辟结点的坐标 */
}
void Free(SLinkList space,int k) /* 算法2.16 */
{ /* 将下标为k的空闲结点回收到备用链表(成为备用链表的第一个结点) */
space[k].cur=space[0].cur; /* 回收结点的"游标"指向备用链表的第一个结点 */
space[0].cur=k; /* 备用链表的头结点指向新回收的结点 */
}
void DestroyList()
{ /* 静态数组不能被销毁 */
}
/* bo2-32.c 一个数组可生成若干静态链表(数据结构由c2-3.h定义)的基本操作(12个) */
void InitSpace(SLinkList L) /* 算法2.14。另加 */
{ /* 将一维数组L中各分量链成一个备用链表,L[0].cur为头指针。“0”表示空指针 */
int i;
for(i=0;i<MAXSIZE-1;i++){
L[i].cur=i+1;
L[i].data = ' ';
}
L[MAXSIZE-1].data = ' ';
L[MAXSIZE-1].cur=0;
#if 1
printf("MAXSIZE = %d\n",MAXSIZE);
i=0;
while(i < MAXSIZE) /* 输出教科书中图2.10(a)的状态 */
{
printf("%3d",i); /* 输出链表的当前值 */
printf("%3s"," ");
i++ ;
}
printf("\n");
i=0;
while(i < MAXSIZE) /* 输出教科书中图2.10(a)的状态 */
{
printf("%3d",L[i].cur); /* 输出链表的当前值 */
printf("%3s"," ");
i++ ;
}
printf("\n");
#endif
}
int InitList(SLinkList L)
{ /* 构造一个空链表,返回值为空表在数组中的位序 */
int i;
i=Malloc(L); /* 调用Malloc(),简化程序 */
L[i].cur=0; /* 空链表的表头指针为空(0) */
return i;
}
Status ClearList(SLinkList L,int n)
{ /* 初始条件:L中表头位序为n的静态链表已存在。操作结果:将此表重置为空表 */
int j,k,i=L[n].cur; /* 链表第一个结点的位置 */
L[n].cur=0; /* 链表空 */
k=L[0].cur; /* 备用链表第一个结点的位置 */
L[0].cur=i; /* 把链表的结点连到备用链表的表头 */
while(i) /* 没到链表尾 */
{
j=i;
i=L[i].cur; /* 指向下一个元素 */
}
L[j].cur=k; /* 备用链表的第一个结点接到链表的尾部 */
return OK;
}
Status ListEmpty(SLinkList L,int n)
{ /* 判断L中表头位序为n的链表是否空,若是空表返回TRUE;否则返回FALSE */
if(L[n].cur==0) /* 空表 */
return TRUE;
else
return FALSE;
}
int ListLength(SLinkList L,int n)
{ /* 返回L中表头位序为n的链表的数据元素个数 */
int j=0,i=L[n].cur; /* i指向第一个元素 */
while(i) /* 没到静态链表尾 */
{
i=L[i].cur; /* 指向下一个元素 */
j++;
}
return j;
}
Status GetElem(SLinkList L,int n, int i,ElemType *e)
{ /* 用e返回L中表头位序为n的链表的第i个元素的值 */
int l,k=n; /* k指向表头序号 */
if(i<1||i>ListLength(L,n)) /* i值不合理 */
return ERROR;
for(l=1;l<=i;l++) /* 移动i-1个元素 */
k=L[k].cur;
*e=L[k].data;
return OK;
}
int LocateElem(SLinkList L,int n,ElemType e)
{ /* 在L中表头位序为n的静态单链表中查找第1个值为e的元素。 */
/* 若找到,则返回它在L中的位序,否则返回0 */
int i=L[n].cur; /* i指示表中第一个结点 */
while(i&&L[i].data!=e) /* 在表中顺链查找(e不能是字符串) */
i=L[i].cur;
return i;
}
Status PriorElem(SLinkList L,int n,ElemType cur_e,ElemType *pre_e)
{ /* 初始条件:在L中表头位序为n的静态单链表已存在 */
/* 操作结果:若cur_e是此单链表的数据元素,且不是第一个, */
/* 则用pre_e返回它的前驱,否则操作失败,pre_e无定义 */
int j,i=L[n].cur; /* i为链表第一个结点的位置 */
do
{ /* 向后移动结点 */
j=i;
i=L[i].cur;
}while(i&&cur_e!=L[i].data);
if(i) /* 找到该元素 */
{
*pre_e=L[j].data;
return OK;
}
return ERROR;
}
Status NextElem(SLinkList L,int n,ElemType cur_e,ElemType *next_e)
{ /* 初始条件:在L中表头位序为n的静态单链表已存在 */
/* 操作结果:若cur_e是此单链表的数据元素,且不是最后一个, */
/* 则用next_e返回它的后继,否则操作失败,next_e无定义 */
int i;
i=LocateElem(L,n,cur_e); /* 在链表中查找第一个值为cur_e的元素的位置 */
if(i) /* 在静态单链表中存在元素cur_e */
{
i=L[i].cur; /* cur_e的后继的位置 */
if(i) /* cur_e有后继 */
{
*next_e=L[i].data;
return OK; /* cur_e元素有后继 */
}
}
return ERROR; /* L不存在cur_e元素,cur_e元素无后继 */
}
Status ListInsert(SLinkList L,int n,int i,ElemType e)
{ /* 在L中表头位序为n的链表的第i个元素之前插入新的数据元素e */
int l,j,k=n; /* k指向表头 */
if(i<1||i>ListLength(L,n)+1)
return ERROR;
j=Malloc(L); /* 申请新单元 */
if(j) /* 申请成功 */
{
L[j].data=e; /* 赋值给新单元 */
for(l=1;l<i;l++) /* 移动i-1个元素 */
k=L[k].cur;
L[j].cur=L[k].cur;
L[k].cur=j;
return OK;
}
return ERROR;
}
Status ListDelete(SLinkList L,int n,int i,ElemType *e)
{ /* 删除在L中表头位序为n的链表的第i个数据元素e,并返回其值 */
int j,k=n; /* k指向表头 */
if(i<1||i>ListLength(L,n))
return ERROR;
for(j=1;j<i;j++) /* 移动i-1个元素 */
k=L[k].cur;
j=L[k].cur;
L[k].cur=L[j].cur;
*e=L[j].data;
Free(L,j);
return OK;
}
Status ListTraverse(SLinkList L,int n,void(*vi)(ElemType))
{ /* 依次对L中表头位序为n的链表的每个数据元素,调用函数vi()。一旦vi()失败,则操作失败 */
int i=L[n].cur; /* 指向第一个元素 */
while(i) /* 没到静态链表尾 */
{
vi(L[i].data); /* 调用vi() */
i=L[i].cur; /* 指向下一个元素 */
}
printf("\n");
return OK;
}
void show_space_content(SLinkList space)
{ int i ;
printf("\n\n\nMAXSIZE = %d\n",MAXSIZE);
i=0;
while(i < MAXSIZE) /* 输出教科书中图2.10(a)的状态 */
{
printf("%3d",i); /* 输出链表的当前值 */
printf("%3s"," ");
i++ ;
}
printf("\n");
i=0;
while(i < MAXSIZE) /* 输出教科书中图2.10(a)的状态 */
{
printf("%3c",space[i].data); /* 输出链表的当前值 */
printf("%3s"," ");
i++ ;
}
printf("\n");
i=0;
while(i < MAXSIZE) /* 输出教科书中图2.10(a)的状态 */
{
printf("%3d",space[i].cur); /* 输出链表的当前值 */
printf("%3s"," ");
i++ ;
}
printf("\n");
}
void difference_abc(SLinkList space,
int *pt_start,
char *ArrayA,
int arraya_len,
char *ArrayB,
int arrayb_len
)
{
int head ; //静态链表 头结点
int tail ; //静态链表 尾结点
int i ;
int index = 0 ;
InitSpace(space);
show_space_content(space);
head = Malloc(space);
show_space_content(space);
*pt_start = head ;
tail = head ;
for(i=0;i<arraya_len;i++)
{
index = Malloc(space);
show_space_content(space);
space[index].data = ArrayA[i];
space[tail].cur = index ;
tail = index ;
}
space[tail].cur = 0 ;
show_space_content(space);
int pos = 0 ;
int pre_pos =0 ;
printf("\n\n begin to compare: \n\n");
for(i=0; i< arrayb_len; i++)
{
pos = space[head].cur ;
pre_pos = pos ;
while(pos !=space[tail].cur){
if(space[pos].data == ArrayB[i]){
break ;
}
pre_pos = pos ;
pos = space[pos].cur ;
}
if(pos == space[tail].cur){
/* 当前表中不存在该元素,插入在tail所指结点之后,且tail的位置不变 */
printf("new %c\n", ArrayB[i]);
index=Malloc(space);
space[index].data=ArrayB[i];
space[index].cur=space[tail].cur;
space[tail].cur=index;
show_space_content(space);
}else{/* 该元素已在表中,删除之 */
space[pre_pos].cur=space[pos].cur;
printf("delete %c\n", ArrayB[i]);
Free(space,pos);
show_space_content(space);
if(tail==pos){
tail=pre_pos; /* 若删除的是尾元素,则需修改尾指针 */
}
}
}
show_space_content(space);
}
void difference(SLinkList space,int *S) /* 算法2.17 */
{ /* 依次输入集合A和B的元素,在一维数组space中建立表示集合(A-B)∪(B-A) */
/* 的静态链表,S为其头指针。假设备用空间足够大,space[0].cur为备用空间的头指针 */
int r,p,m,n,i,j,k;
ElemType b;
ElemType ch ;
InitSpace(space); /* 初始化备用空间 */
*S=Malloc(space); /* 生成S的头结点 */
r=*S; /* r指向S的当前最后结点 */
printf("r = %d\n",r);
printf("请输入集合A的元素个数m:\n");
scanf("%d",&m);
scanf("%*c"); /* %*c吃掉回车符 */
printf("m = %d\n",m);
//printf("请输入集合A和B的元素个数m,n:");
//scanf("%d,%d%*c",&m,&n); /* %*c吃掉回车符 */
printf("请输入集合A的元素(共%d个):\n",m);
for(j=1;j<=m;j++) /* 建立集合A的链表 */
{
i=Malloc(space); /* 分配结点 */
scanf("%c",&ch); /* 输入A的元素值 */
printf("%c -- %d\n",ch,i);
space[i].data = ch ;
space[r].cur=i; /* 插入到表尾 */
printf("i = %d,r = %d, ch = %c\n",i, r,ch);
r=i;
}
printf("i = %d,r = %d, ch = %c\n",i, r,ch);
scanf("%*c"); /* %*c吃掉回车符 */
space[r].cur=0; /* 尾结点的指针为空 */
printf("请输入集合B的元素个数n:\n");
scanf("%d",&n);
scanf("%*c"); /* %*c吃掉回车符 */
printf("n = %d\n",n);
printf("请输入集合B的元素(共%d个):\n",n);
for(j=1;j<=n;j++)
{ /* 依次输入B的元素,若不在当前表中,则插入,否则删除 */
scanf("%c",&b);
printf("b = %c\n",b);
p=*S;
k=space[*S].cur; /* k指向集合A中的第一个结点 */
printf("k = %d\n",k);
while(k!=space[r].cur&&space[k].data!=b)
{ /* 在当前表中查找 */
p=k;
k=space[k].cur;
}
printf("refer data : cbegfd\n");
printf("p=%d,k=%d,r =%d, space[r].cur = %d\n\n\n",p,k,r,space[r].cur);
if(k==space[r].cur)
{ /* 当前表中不存在该元素,插入在r所指结点之后,且r的位置不变 */
i=Malloc(space);
space[i].data=b;
space[i].cur=space[r].cur;
space[r].cur=i;
printf("\n not exist \n");
}
else /* 该元素已在表中,删除之 */
{
space[p].cur=space[k].cur;
Free(space,k);
if(r==k){
r=p; /* 若删除的是尾元素,则需修改尾指针 */
}
printf("\n exist \n");
}
}
scanf("%*c"); /* %*c吃掉回车符 */
}
void visit(ElemType c)
{
printf("%c ",c);
}
void main()
{
int k;
SLinkList s;
int m ;
int n ;
int i ;
int ch ;
char ArrayA[MAXSIZE];
int arrayA_cnt = 0 ;
char ArrayB[MAXSIZE];
int arrayB_cnt = 0 ;
printf("请输入集合A的元素个数m: %d\n",6);
printf("请输入集合A的元素(共6个):cbegfd\n");
printf("请输入集合B的元素个数n:%d\n",4);
printf("请输入集合B的元素(共4个):abnf\n");
printf("c e g d n a\n");
printf("请输入集合A的元素个数m--(eg:6):\n");
scanf("%d",&m);
scanf("%*c"); /* %*c吃掉回车符 */
printf("m = %d\n",m);
printf("请输入集合A的元素(共%d个):(eg:cbegfd)\n",m);
for(i=0; i<m;i++){
ch = getchar();
ArrayA[i] = ch ;
arrayA_cnt++ ;
}
printf("请输入集合B的元素个数n:(eg:4)\n");
scanf("%d",&n);
scanf("%*c"); /* %*c吃掉回车符 */
printf("n = %d\n",n);
printf("请输入集合B的元素(共%d个): (eg: abnf)\n",n);
for(i=0; i<n;i++){
ch = getchar();
ArrayB[i] = ch ;
arrayB_cnt++ ;
}
// difference(s,&k);
//printf("\nk = %d\n", k);
difference_abc(s,&k,ArrayA,arrayA_cnt,ArrayB,arrayB_cnt);
ListTraverse(s,k,visit);
}
运行效果:
请输入集合A的元素个数m: 6
请输入集合A的元素(共6个):cbegfd
请输入集合B的元素个数n:4
请输入集合B的元素(共4个):abnf
c e g d n a
请输入集合A的元素个数m--(eg:6):
6
m = 6
请输入集合A的元素(共6个):(eg:cbegfd)
cbegfd
请输入集合B的元素个数n:(eg:4)
4
n = 4
请输入集合B的元素(共4个): (eg: abnf)
abnf
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
1 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
2 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
3 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c
4 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b
5 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b e
6 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b e g
7 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b e g f
8 2 3 4 5 6 7 8 9 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b e g f d
8 2 3 4 5 6 7 0 9 10 11 0
begin to compare:
new a
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b e g f d a
9 2 3 4 5 6 7 8 0 10 11 0
delete b
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c b e g f d a
3 2 4 9 5 6 7 8 0 10 11 0
new n
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c n e g f d a
9 2 4 8 5 6 7 3 0 10 11 0
delete f
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c n e g f d a
6 2 4 8 5 7 9 3 0 10 11 0
MAXSIZE = 12
0 1 2 3 4 5 6 7 8 9 10 11
c n e g f d a
6 2 4 8 5 7 9 3 0 10 11 0
c e g d n a