数据结构 设计性实验 广义表的抽象数据类型.docx

上传人:b****6 文档编号:6626805 上传时间:2023-01-08 格式:DOCX 页数:23 大小:204.97KB
下载 相关 举报
数据结构 设计性实验 广义表的抽象数据类型.docx_第1页
第1页 / 共23页
数据结构 设计性实验 广义表的抽象数据类型.docx_第2页
第2页 / 共23页
数据结构 设计性实验 广义表的抽象数据类型.docx_第3页
第3页 / 共23页
数据结构 设计性实验 广义表的抽象数据类型.docx_第4页
第4页 / 共23页
数据结构 设计性实验 广义表的抽象数据类型.docx_第5页
第5页 / 共23页
点击查看更多>>
下载资源
资源描述

数据结构 设计性实验 广义表的抽象数据类型.docx

《数据结构 设计性实验 广义表的抽象数据类型.docx》由会员分享,可在线阅读,更多相关《数据结构 设计性实验 广义表的抽象数据类型.docx(23页珍藏版)》请在冰豆网上搜索。

数据结构 设计性实验 广义表的抽象数据类型.docx

数据结构设计性实验广义表的抽象数据类型

题目:

广义表的抽象数据类型

抽象数据类型广义表的定义

基本操作:

  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;若S

inti;

for(i=0;i

if(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).length

exit(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;i

printf("%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-

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1