//在VC++6.0下编译
#include <iostream.h>
typedef char ElemType;
enum Bool{False,True};
//广义表的一个结点,
struct GLnode
{
Bool tag; //用于识别是原子还是子表(这里假定1为子表,0为原子)
union
{
ElemType data;//原子使用这一项,用于存储数据
GLnode *sublist;//子表使用这一项,用于指向一个新的子广域表
};
GLnode *next;//指向下一个结点
};
/*
* 一个广域表要不含有原子,要不就含有子表(另一个广域表)。子表和原子都可增加广域表的长度,而子表则可增加广域表的深度。
*创建或打印一个广域表,是一个双向任务,一是横向创建打印广域表长度,二是创建打印广域表的深度。
*可以看到,递归函数中都将有两个分支,一个横向一个纵向
*
*横向递归的出口是next域为空,即没有了后继结点。
*纵向递归的出口是data域或sublist域为空,即没有下一层。
*/
//创建一个广域表
void Create(GLnode *& GL)
{
char ch;
cin>>ch;
if(ch=='#')
GL=NULL;
else if( ch=='(' )
{
GL=new GLnode;//创建一个新的子表结点
GL->tag=True;
Create(GL->sublist);//递归调用纵向分支
}
else
{
GL=new GLnode;//创建一个新的原子结点
GL->tag=False;
GL->data=ch;
}
cin>>ch;
if(GL==NULL)
; //此时的ch必然为')',什么都不做
else if(ch==',')
Create(GL->next);//递归调用横向分支
else if((ch==')') || (ch==';'))
GL->next=NULL;
}
void Print(GLnode *GL)
{
if(GL->tag==True)//若是子表,则需打印'(',在打印此子表(递归调用)
{
cout<<'(';
if(GL->sublist==NULL)
cout<<'#';//递归出口点
else
Print(GL->sublist);//递归的纵向分支
}
else //如果是原子,则输出其数据
cout<<GL->data;
if(GL->tag==True)
cout<<')';
if(GL->next!=NULL)
{
cout<<',';
Print(GL->next);//递归的横向分支
}
}
//求广域表的长度
/*
//常规方法
int Length(GLnode *GL)
{
int c=0;
while(GL!=NULL)
{
c++;
GL=GL->next;
}
return c;
}
*/
//递归方法
int Length(GLnode *GL)
{
if(GL!=NULL)
return 1+Length(GL->next);
else
return 0;
}
main()
{
GLnode *G;
Create(G);
Print(G);
cout<<endl;
cout<<"Length="<<Length(G->sublist)<<endl;
}
/*
(a,(b,c,d),(e,(f),()))
;
层次结构
G
a, ( ), ( )
b,c,d e, ( ), ( )
f
*/