数据结构 设计性实验 广义表的抽象数据类型.docx
《数据结构 设计性实验 广义表的抽象数据类型.docx》由会员分享,可在线阅读,更多相关《数据结构 设计性实验 广义表的抽象数据类型.docx(23页珍藏版)》请在冰豆网上搜索。
![数据结构 设计性实验 广义表的抽象数据类型.docx](https://file1.bdocx.com/fileroot1/2023-1/8/0bd87eb0-b4e8-4840-9bea-0861b782dfc6/0bd87eb0-b4e8-4840-9bea-0861b782dfc61.gif)
数据结构设计性实验广义表的抽象数据类型
题目:
广义表的抽象数据类型
抽象数据类型广义表的定义
基本操作:
InitGList(&L);
操作结果:
创建空的广义表L。
CreateGList(&L,S);
初始条件:
S是广义表的书写形式串。
操作结果:
由S创建广义表L。
DestroyGList(&L);
初始条件:
广义表L存在。
操作结果:
销毁广义表L。
CopyGList(&T,L);
初始条件:
广义表L存在。
操作结果:
由广义表L复制得到广义表T。
GlistLength(L);
初始条件:
广义表L存在。
操作结果:
求广义表L的长度,即元素个数。
GlistDepth(L);
初始条件:
广义表L存在。
操作结果:
求广义表的深度。
GlistEmpty(L);
初始条件:
广义表L存在。
操作结果:
判定广义表L是否为空。
GetHead(L);
初始条件:
广义表L存在。
操作结果:
取广义表L的头。
GetTail(L);
初始条件:
广义表L存在。
操作结果:
取广义表L的尾。
InsertFirst_GL(&L,e);
初始条件:
广义表L存在。
操作结果:
插入元素e作为广义表L的第一元素。
DeleteFirst_GL(&L,&e);
初始条件:
广义表L存在。
操作结果:
删除广义表L的第一元素,并用e返回其值。
Traverse_GL(L,Visit());
初始条件:
广义表L存在。
。
操作结果:
遍历广义表L,用函数Visit处理每个元素。
}ADT
存储结构定义
由于广义表中的数据元素可以具有不同的结构,(或是原子,或是列表),因此难以用顺序存储结构表示,通常有采用链式存储结构,每个数据元素可用一个结点表示。
由于列表中的数据元素可能为原子或列表,由此需要两种结构的结点:
一种是表结点,以表示列表;一种是原子结点,用以表示原子。
若列不空,则可分解成表头和表尾;反之,一对确定的表头和表尾可唯一确定列表。
由此,一个表结点可由三个域组成:
标志域、指示域和指示表尾的指针域;而原子结点只需两个域:
标志域和值域(如图8所示)。
其形式定义说明如下:
存储结构:
公用头文件DS0.h:
#include#include
#include#include
#include#include
#include#include
#include#defineTRUE1
#defineFALSE0#defineOK1
#defineERROR0#defineINFEASIBLE-1
typedefcharAtomType;/*定义原子类型为字符型*/
//-----------广义表的头尾链表存储表示------------//
typedefenum{ATOM,LIST}ElemTag;//
ATOM==0:
原子,LIST==1:
子表
typedefstructGLNode{
ElemTagtag;//公共部分,用于区分原子结点和表结点
union{//原子结点和表结点的联合部分
AtomTypeatom;//atom是原子结点的值域,AtomType由用户定义
Struct{structGLNode*hp,*tp;}ptr;
//ptr是表结点的指针域,ptr.hp和ptr.tp分别指向表头和表尾
};
}*Glist;//广义表类型
//---------广义表的扩展线性链表存储表示----------//
typedefenum{ATOM,LIST}ElemTag;//ATOM==0:
原子,LIST==1:
子表
typedefstructGLNode{
ElemTagtag;//公共部分,用于区分原子结点和表结点
union{//原子结点和表结点的联合部分
AtomTypeatom;//原子结点的值域
StructGLNode*hp;//表结点的表头指针
};
structGLNode*tp;//相当于线性链表的next,指向下一个元素结点
}*Glist;//广义表类型Glist是一种扩展的线性链表
四,算法设计
#include
#include
#include
#include
#include
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineOK1
#defineERROR0
#defineINFEASIBLE-1
typedefcharAtomType;/*定义原子类型为字符型*/
typedefintStatus;/*Status是函数的类型,其值是函数结果状态代码,如OK等*/
typedefintBoolean;
typedefstruct
{
char*ch;/*若是非空串,则按串长分配存储区,否则ch为NULL*/
intlength;/*串长度*/
}HString;
typedefenum{ATOM,LIST}ElemTag;/*ATOM==0:
原子,LIST==1:
子表*/
typedefstructGLNode
{
ElemTagtag;
union
{
AtomTypeatom;
structGLNode*hp;
}a;
structGLNode*tp;
}*GList,GLNode;
StatusStrAssign(HString*T,char*chars)
{
inti,j;
if((*T).ch)
free((*T).ch);
i=strlen(chars);
if(!
i)
{
(*T).ch=NULL;
(*T).length=0;
}
else
{/*chars的长度不为0*/
(*T).ch=(char*)malloc(i*sizeof(char));
if(!
(*T).ch)/*分配串空间失败*/
exit(OVERFLOW);
for(j=0;j
(*T).ch[j]=chars[j];
(*T).length=i;
}
returnOK;
}
StatusStrCopy(HString*T,HStringS)
{/*初始条件:
串S存在。
操作结果:
由串S复制得串T*/
inti;
if((*T).ch)
free((*T).ch);
(*T).ch=(char*)malloc(S.length*sizeof(char));
if(!
(*T).ch)
exit(OVERFLOW);
for(i=0;i(*T).ch[i]=S.ch[i];
(*T).length=S.length;
returnOK;
}
StatusStrEmpty(HStringS)
{/*初始条件:
串S存在。
操作结果:
若S为空串,则返回TRUE,否则返回FALSE*/
if(S.length==0&&S.ch==NULL)
returnTRUE;
else
returnFALSE;
}
intStrCompare(HStringS,HStringT)
{/*若S>T,则返回值>0;若S=T,则返回值=0;若Sinti;
for(i=0;iif(S.ch[i]!
=T.ch[i])
returnS.ch[i]-T.ch[i];
returnS.length-T.length;
}
intStrLength(HStringS)
{/*返回S的元素个数,称为串的长度*/
returnS.length;
}
StatusClearString(HString*S)
{/*将S清为空串*/
if((*S).ch)
{
free((*S).ch);
(*S).ch=NULL;
}
(*S).length=0;
returnOK;
}
StatusConcat(HString*T,HStringS1,HStringS2)
{/*用T返回由S1和S2联接而成的新串*/
inti;
if((*T).ch)
free((*T).ch);/*释放旧空间*/
(*T).length=S1.length+S2.length;
(*T).ch=(char*)malloc((*T).length*sizeof(char));
if(!
(*T).ch)
exit(OVERFLOW);
for(i=0;i(*T).ch[i]=S1.ch[i];
for(i=0;i(*T).ch[S1.length+i]=S2.ch[i];
returnOK;
}
StatusSubString(HString*Sub,HStringS,intpos,intlen)
{/*用Sub返回串S的第pos个字符起长度为len的子串。
*/
/*其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1*/
inti;
if(pos<1||pos>S.length||len<0||len>S.length-pos+1)
returnERROR;
if((*Sub).ch)
free((*Sub).ch);/*释放旧空间*/
if(!
len)/*空子串*/
{
(*Sub).ch=NULL;
(*Sub).length=0;
}
else
{/*完整子串*/
(*Sub).ch=(char*)malloc(len*sizeof(char));
if(!
(*Sub).ch)
exit(OVERFLOW);
for(i=0;i<=len-1;i++)
(*Sub).ch[i]=S.ch[pos-1+i];
(*Sub).length=len;
}
returnOK;
}
voidInitString(HString*T)
{/*初始化(产生空串)字符串T。
另加*/
(*T).length=0;
(*T).ch=NULL;
}
intIndex(HStringS,HStringT,intpos)/*算法4.1*/
{/*T为非空串。
若主串S中第pos个字符之后存在与T相等的子串,*/
/*则返回第一个这样的子串在S中的位置,否则返回0*/
intn,m,i;
HStringsub;
InitString(&sub);
if(pos>0)
{
n=StrLength(S);
m=StrLength(T);
i=pos;
while(i<=n-m+1)
{
SubString(&sub,S,i,m);
if(StrCompare(sub,T)!
=0)
++i;
else
returni;
}
}
return0;
}
StatusStrInsert(HString*S,intpos,HStringT)/*算法4.4*/
{/*1≤pos≤StrLength(S)+1。
在串S的第pos个字符之前插入串T*/
inti;
if(pos<1||pos>(*S).length+1)/*pos不合法*/
returnERROR;
if(T.length)/*T非空,则重新分配空间,插入T*/
{
(*S).ch=(char*)realloc((*S).ch,((*S).length+T.length)*sizeof(char));
if(!
(*S).ch)
exit(OVERFLOW);
for(i=(*S).length-1;i>=pos-1;--i)/*为插入T而腾出位置*/
(*S).ch[i+T.length]=(*S).ch[i];
for(i=0;i(*S).ch[pos-1+i]=T.ch[i];/*插入T*/
(*S).length+=T.length;
}
returnOK;
}
StatusStrDelete(HString*S,intpos,intlen)
{/*从串S中删除第pos个字符起长度为len的子串*/
inti;
if((*S).lengthexit(ERROR);
for(i=pos-1;i<=(*S).length-len;i++)
(*S).ch[i]=(*S).ch[i+len];
(*S).length-=len;
(*S).ch=(char*)realloc((*S).ch,(*S).length*sizeof(char));
returnOK;
}
StatusReplace(HString*S,HStringT,HStringV)
{/*初始条件:
串S,T和V存在,T是非空串(此函数与串的存储结构无关)*/
/*操作结果:
用V替换主串S中出现的所有与T相等的不重叠的子串*/
inti=1;/*从串S的第一个字符起查找串T*/
if(StrEmpty(T))/*T是空串*/
returnERROR;
do
{
i=Index(*S,T,i);
if(i)
{
StrDelete(S,i,StrLength(T));
StrInsert(S,i,V);
i+=StrLength(V);
}
}while(i);
returnOK;
}
voidDestroyString()
{/*堆分配类型的字符串无法销毁*/
}
voidStrPrint(HStringT)
{/*输出T字符串。
另加*/
inti;
for(i=0;iprintf("%c",T.ch[i]);
printf("\n");
}
/*广义表的书写形式串为HString类型*/
StatusInitGList(GList*L)
{/*创建空的广义表L*/
*L=NULL;
returnOK;
}
Statussever(HString*str,HString*hstr)/*同bo5-52.c*/
{/*将非空串str分割成两部分:
hstr为第一个','之前的子串,str为之后的子串*/
intn,i=1,k=0;/*k记尚未配对的左括号个数*/
HStringch,c1,c2,c3;
InitString(&ch);/*初始化HString类型的变量*/
InitString(&c1);
InitString(&c2);
InitString(&c3);
StrAssign(&c1,",");
StrAssign(&c2,"(");
StrAssign(&c3,")");
n=StrLength(*str);
do
{
SubString(&ch,*str,i,1);
if(!
StrCompare(ch,c2))
++k;
elseif(!
StrCompare(ch,c3))
--k;
++i;
}while(i<=n&&StrCompare(ch,c1)||k!
=0);
if(i<=n)
{
StrCopy(&ch,*str);
SubString(hstr,ch,1,i-2);
SubString(str,ch,i,n-i+1);
}
else
{
StrCopy(hstr,*str);
ClearString(str);
}
returnOK;
}
StatusCreateGList(GList*L,HStringS)
{/*初始条件:
S是广义表的书写形式串。
操作结果:
由S创建广义表L*/
HStringemp,sub,hsub;
GListp;
InitString(&emp);
InitString(&sub);
InitString(&hsub);
StrAssign(&emp,"()");/*设emp="()"*/
*L=(GList)malloc(sizeof(GLNode));
if(!
*L)/*建表结点不成功*/
exit(OVERFLOW);
if(!
StrCompare(S,emp))/*创建空表*/
{
(*L)->tag=LIST;
(*L)->a.hp=NULL;
(*L)->tp=NULL;
}
elseif(StrLength(S)==1)/*创建单原子广义表*/
{
(*L)->tag=ATOM;
(*L)->a.atom=S.ch[0];
(*L)->tp=NULL;
}
else/*创建一般表*/
{
(*L)->tag=LIST;
(*L)->tp=NULL;
SubString(&sub,S,2,StrLength(S)-2);/*脱外层括号*/
sever(&sub,&hsub);/*从sub中分离出表头串hsub*/
CreateGList(&(*L)->a.hp,hsub);
p=(*L)->a.hp;
while(!
StrEmpty(sub))/*表尾不空,则重复建n个子表*/
{
sever(&sub,&hsub);/*从sub中分离出表头串hsub*/
CreateGList(&p->tp,hsub);
p=p->tp;
};
}
returnOK;
}
voidDestroyGList(GList*L)
{/*初始条件:
广义表L存在。
操作结果:
销毁广义表L*/
GListph,pt;
if(*L)/*L不为空表*/
{/*由ph和pt接替L的两个指针*/
if((*L)->tag)/*是子表*/
ph=(*L)->a.hp;
else/*是原子*/
ph=NULL;
pt=(*L)->tp;
free(*L);/*释放L所指结点*/
*L=NULL;/*令L为空*/
DestroyGList(&ph);/*递归销毁表ph*/
DestroyGList(&pt);/*递归销毁表pt*/
}
}
StatusCopyGList(GList*T,GListL)
{/*初始条件:
广义表L存在。
操作结果:
由广义表L复制得到广义表T*/
if(!
L)/*L空*/
{
*T=NULL;
returnOK;
}
*T=(GList)malloc(sizeof(GLNode));
if(!
*T)
exit(OVERFLOW);
(*T)->tag=L->tag;/*复制枚举变量*/
if(L->tag==ATOM)/*复制共用体部分*/
(*T)->a.atom=L->a.atom;/*复制单原子*/
else
CopyGList(&(*T)->a.hp,L->a.hp);/*复制子表*/
if(L->tp==NULL)/*到表尾*/
(*T)->tp=L->tp;
else
CopyGList(&(*T)->tp,L->tp);/*复制子表*/
returnOK;
}
intGListLength(GListL)
{/*初始条件:
广义表L存在。
操作结果:
求广义表L的长度,即元素个数*/
intlen=0;
GListp;
if(L->tag==LIST&&!
L->a.hp)/*空表*/
return0;/*空表返回0*/
elseif(L->tag==ATOM)/*单原子表*/
return1;
else/*一般表*/
{
p=L->a.hp;
do
{
len++;
p=p->tp;
}while(p);
returnlen;
}
}
intGListDepth(GListL)
{/*初始条件:
广义表L存在。
操作结果:
求广义表L的深度*/
intmax,dep;
GListpp;
if(L==NULL||L->tag==LIST&&!
L->a.hp)
return1;/*空表深度为1*/
elseif(L->tag==ATOM)
return0;/*单原子表深度为0*/
else/*求一般表的深度*/
for(max=0,pp=L->a.hp;pp;pp=pp->tp)
{
dep=GListDepth(pp);/*求以pp为头指针的子表深度*/
if(dep>max)
max=dep;
}
returnmax+1;/*非空表的深度是各元素的深度的最大值加1*/
}
StatusGListEmpty(GListL)
{/*初始条件:
广义表L存在。
操作结果:
判定广义表L是否为空*/
if(!
L||L->tag==LIST&&!
L->a.hp)
returnOK;
else
returnERROR;
}
GListGetHead(GListL)
{/*初始条件:
广义表L存在。
操作结果:
取广义表L的头*/
GListh;
InitGList(&h);
if(!
L||L->tag==LIST&&!
L-