数据结构C语言版广义表的头尾链表存储表示.docx
- 文档编号:28274242
- 上传时间:2023-07-10
- 格式:DOCX
- 页数:17
- 大小:18.39KB
数据结构C语言版广义表的头尾链表存储表示.docx
《数据结构C语言版广义表的头尾链表存储表示.docx》由会员分享,可在线阅读,更多相关《数据结构C语言版广义表的头尾链表存储表示.docx(17页珍藏版)》请在冰豆网上搜索。
数据结构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 请按任意键继续... */
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数据结构 语言版 广义 头尾 存储 表示