数据结构C语言版广义表的头尾链表存储表示.docx

上传人:b****5 文档编号:28274242 上传时间:2023-07-10 格式:DOCX 页数:17 大小:18.39KB
下载 相关 举报
数据结构C语言版广义表的头尾链表存储表示.docx_第1页
第1页 / 共17页
数据结构C语言版广义表的头尾链表存储表示.docx_第2页
第2页 / 共17页
数据结构C语言版广义表的头尾链表存储表示.docx_第3页
第3页 / 共17页
数据结构C语言版广义表的头尾链表存储表示.docx_第4页
第4页 / 共17页
数据结构C语言版广义表的头尾链表存储表示.docx_第5页
第5页 / 共17页
点击查看更多>>
下载资源
资源描述

数据结构C语言版广义表的头尾链表存储表示.docx

《数据结构C语言版广义表的头尾链表存储表示.docx》由会员分享,可在线阅读,更多相关《数据结构C语言版广义表的头尾链表存储表示.docx(17页珍藏版)》请在冰豆网上搜索。

数据结构C语言版广义表的头尾链表存储表示.docx

数据结构C语言版广义表的头尾链表存储表示

数据结构C语言版广义表的头尾链表存储表示

P109

编译环境:

Dev-C++4.9.9.2

日期:

2011年2月13日

*/

#include

#include

#include

#include

 

typedefcharAtomType;//定义原子类型为字符型

typedefenum{

ATOM,//ATOM==0:

原子

LIST//LIST==1:

子表

}ElemTag;

//广义表的头尾链表存储表示

typedefstructGLNode

{

ElemTagtag;//公共部分,用于区分原子结点和表结点

union//原子结点和表结点的联合部分

{

AtomTypeatom;//atom是原子结点的值域,AtomType由用户定义

struct

{

structGLNode*hp,*tp;

}ptr;//ptr是表结点的指针域,prt.hp和ptr.tp分别指向表头和表尾

}a;

}*GList,GLNode;//广义表类型

 

//创建空的广义表L

intInitGList(GList*L)

{

*L=NULL;

return1;

}

//销毁广义表L

voidDestroyGList(GList*L)

{

GListq1,q2;

if(*L)

{

if((*L)->tag==ATOM)

{

free(*L);//删除原子结点

*L=NULL;

}

else//是表结点,则应该删除表头和表尾结点

{

q1=(*L)->a.ptr.hp;

q2=(*L)->a.ptr.tp;

free(*L);

*L=NULL;

//递归删除表头和表尾结点

DestroyGList(&q1);

DestroyGList(&q2);

}

}

}

//算法5.6P115

//采用头尾链表存储结构,由广义表L复制得到广义表T。

intCopyGList(GList*T,GListL)

{

if(!

L)//为空,复制空表

*T=NULL;

else

{

*T=(GList)malloc(sizeof(GLNode));//建表结点

if(!

*T)

exit(0);

(*T)->tag=L->tag;

if(L->tag==ATOM)

(*T)->a.atom=L->a.atom;//复制单原子

else//是表结点,则依次复制表头和表尾

{

//复制广义表L->ptr.hp的一个副本T->ptr.hp

CopyGList(&((*T)->a.ptr.hp),L->a.ptr.hp);

//复制广义表L->ptr.tp的一个副本T->ptr.tp

CopyGList(&((*T)->a.ptr.tp),L->a.ptr.tp);

}

}

return1;

}

//返回广义表的长度,即元素个数

intGListLength(GListL)

{

intlen=0;

if(!

L)

return0;

if(L->tag==ATOM)

return1;

while(L)

{

L=L->a.ptr.tp;//根据表尾来判断

len++;

}

returnlen;

}

//算法5.5P114

//采用头尾链表存储结构,求广义表L的深度。

intGListDepth(GListL)

{

intmax,dep;

GListpp;

if(!

L)

return1;//空表深度为1

if(L->tag==ATOM)

return0;//原子深度为0

for(max=0,pp=L;pp;pp=pp->a.ptr.tp)

{

//递归求以pp->a.ptr.hp为头指针的子表深度

dep=GListDepth(pp->a.ptr.hp);

if(dep>max)

max=dep;

}

returnmax+1;//非空表的深度是各元素的深度的最大值加1

}

//判定广义表是否为空

intGListEmpty(GListL)

{

if(!

L)

return1;

else

return0;

}

//取广义表L的头

GListGetHead(GListL)

{

GListh,p;

if(!

L)

{

printf("空表无表头!

\n");

exit(0);

}

p=L->a.ptr.tp;//保存表尾

L->a.ptr.tp=NULL;

CopyGList(&h,L);

L->a.ptr.tp=p;//归还表尾

returnh;

}

//取广义表L的尾

GListGetTail(GListL)

{

GListt;

if(!

L)

{

printf("空表无表尾!

\n");

exit(0);

}

CopyGList(&t,L->a.ptr.tp);

returnt;

}

//插入元素e作为广义表L的第一元素(表头,也可能是子表)

intInsertFirst_GL(GList*L,GListe)

{

GListp=(GList)malloc(sizeof(GLNode));

if(!

p)

exit(0);

p->tag=LIST;

p->a.ptr.hp=e;

p->a.ptr.tp=*L;

*L=p;

return1;

}

//删除广义表L的第一元素,并用e返回其值

intDeleteFirst_GL(GList*L,GList*e)

{

GListp;

*e=(*L)->a.ptr.hp;//用*e返回表头

p=*L;

*L=(*L)->a.ptr.tp;//将表尾当成表L

free(p);//删除表头

return1;

}

//利用递归算法遍历广义表L

voidTraverse_GL(GListL,void(*v)(AtomType))

{

if(L)//L不空

if(L->tag==ATOM)//L为单原子

v(L->a.atom);

else//L为广义表

{

Traverse_GL(L->a.ptr.hp,v);

Traverse_GL(L->a.ptr.tp,v);

}

}

//串的定长顺序存储表示

#defineMAXSTRLEN40//用户可在255以内定义最大串长(1个字节)

typedefcharSString[MAXSTRLEN+1];//0号单元存放串的当前长度

//生成一个其值等于chars的串T

intStrAssign(SStringT,char*chars)

{

inti;

if(strlen(chars)>MAXSTRLEN)

return0;

else

{

T[0]=strlen(chars);//记录长度

//一个一个的拷贝,字符串结束符也拷贝了

for(i=1;i<=T[0];i++)

T[i]=*(chars+i-1);

return1;

}

}

//由串S复制得串T

intStrCopy(SStringT,SStringS)

{

inti;

//一个一个的拷贝

for(i=0;i<=S[0];i++)

T[i]=S[i];

return1;

}

//若S为空串,则返回1,否则返回0

intStrEmpty(SStringS)

{

if(S[0]==0)

return1;

else

return0;

}

//若S>T,则返回值>0;若S=T,则返回值=0;若S

intStrCompare(SStringS,SStringT)

{

inti;

for(i=1;i<=S[0]&&i<=T[0];++i)

if(S[i]!

=T[i])

returnS[i]-T[i];

returnS[0]-T[0];

}

//返回串的元素个数

intStrLength(SStringS)

{

returnS[0];

}

//将S清为空串

intClearString(SStringS)

{

S[0]=0;//令串长为零

return1;

}

//算法4.3P74

//用Sub返回串S的第pos个字符起长度为len的子串。

intSubString(SStringSub,SStringS,intpos,intlen)

{

inti;

if(pos<1||pos>S[0]||len<0||len>S[0]-pos+1)

return0;

for(i=1;i<=len;i++)

Sub[i]=S[pos+i-1];

Sub[0]=len;

return1;

}

//算法5.8P117

//将非空串str分割成两部分:

hsub为第一个','之前的子串,str为之后的子串

voidsever(SStringstr,SStringhstr)

{

intn,i,

k;//k记尚未配对的左括号个数

SStringch,c1,c2,c3;

n=StrLength(str);

StrAssign(c1,",");

StrAssign(c2,"(");

StrAssign(c3,")");

SubString(ch,str,1,1);

//搜索最外层的第一个逗号

for(i=1,k=0;i<=n&&StrCompare(ch,c1)||k!

=0;++i)

{

SubString(ch,str,i,1);

if(!

StrCompare(ch,c2))

++k;

elseif(!

StrCompare(ch,c3))

--k;

}

if(i<=n)

{

SubString(hstr,str,1,i-2);

SubString(str,str,i,n-i+1);

}

else

{

StrCopy(hstr,str);

ClearString(str);

}

}

//算法5.7P117

//采用头尾链表存储结构,由广义表的书写形式串S(即类似(,()))创建

//广义表L。

设emp="()"

intCreateGList(GList*L,SStringS)

{

SStringsub,hsub,emp;

GListp,q;

StrAssign(emp,"()");

if(!

StrCompare(S,emp))

*L=NULL;//创建空表

else

{

*L=(GList)malloc(sizeof(GLNode));

if(!

*L)//建表结点

exit(0);

if(StrLength(S)==1)//S为单原子

{

(*L)->tag=ATOM;

(*L)->a.atom=S[1];//创建单原子广义表

}

else

{

(*L)->tag=LIST;

p=*L;

SubString(sub,S,2,StrLength(S)-2);//脱外层括号

do

{//重复建n个子表

sever(sub,hsub);//从sub中分离出表头串hsub

CreateGList(&p->a.ptr.hp,hsub);

q=p;

if(!

StrEmpty(sub))//表尾不空

{

p=(GLNode*)malloc(sizeof(GLNode));

if(!

p)

exit(0);

p->tag=LIST;

q->a.ptr.tp=p;

}

}while(!

StrEmpty(sub));

q->a.ptr.tp=NULL;

}

}

return1;

}

//打印原子

voidvisit(AtomTypee)

{

printf("%c",e);

}

intmain()

{

//广义表的表示形式是,空表:

(),单原子:

a,表:

(a,(b),c,(d,(e)))

charp[80]={"(a,(b),c,(d,(e)))"};

SStringt;

GListL,m;

InitGList(&L);

InitGList(&m);

printf("空广义表L的深度=%d\nL是否空?

%d(1:

是0:

否)\n\n",

GListDepth(L),GListEmpty(L));

StrAssign(t,p);

//创建广义表

CreateGList(&L,t);

printf("\n广义表L的长度=%d\n",GListLength(L));

printf("广义表L的深度=%d\nL是否空?

%d(1:

是0:

否)\n",

GListDepth(L),GListEmpty(L));

printf("遍历广义表L:

\n");

Traverse_GL(L,visit);

printf("\n\n复制广义表m=L\n");

CopyGList(&m,L);

printf("广义表m的长度=%d\n",GListLength(m));

printf("广义表m的深度=%d\n",GListDepth(m));

printf("遍历广义表m:

\n");

Traverse_GL(m,visit);

//重复用的时候记得销毁,相当于初始化

DestroyGList(&m);

m=GetHead(L);

printf("\n\nm是L的表头,遍历广义表m:

\n");

Traverse_GL(m,visit);

//重复用的时候记得销毁,相当于初始化

DestroyGList(&m);

m=GetTail(L);

printf("\n\nm是L的表尾,遍历广义表m:

\n");

Traverse_GL(m,visit);

//插入到表头

InsertFirst_GL(&m,L);

printf("\n\n插入L为m的表头,遍历广义表m:

\n");

Traverse_GL(m,visit);

printf("\n\n删除m的表头,遍历广义表m:

\n");

DestroyGList(&L);

DeleteFirst_GL(&m,&L);

Traverse_GL(m,visit);

printf("\n");

DestroyGList(&m);

system("pause");

return0;

}

/*

输出效果:

空广义表L的深度=1

L是否空?

1(1:

是0:

否)

 

广义表L的长度=4

广义表L的深度=3

L是否空?

0(1:

是0:

否)

遍历广义表L:

abcde

复制广义表m=L

广义表m的长度=4

广义表m的深度=3

遍历广义表m:

abcde

m是L的表头,遍历广义表m:

a

m是L的表尾,遍历广义表m:

bcde

插入L为m的表头,遍历广义表m:

abcdebcde

删除m的表头,遍历广义表m:

bcde

请按任意键继续...

 

*/

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

当前位置:首页 > 小学教育 > 小学作文

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

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