见代码
#define OVERFLOW -2
typedef enum{ATOM,LIST}ElemTag; //ATOM=0,原子;LIST=1,子表;
typedef char *AtomType; //原子类型
typedef struct GLNode{
ElemTag tag; //公共部分,区别原子结点和表结点
union {
AtomType atom; //原子结点的值域
struct{struct GLNode *hp,*tp;
char *listname;
}ptr; //分指表头和表尾
};
}*GList; //广义表类型
/********************字符串的操作***********************************/
int StrLength(char *s) //返回串长
{return strlen(s);
}
status SubString(char *&sub,char *str,int pos,int len)
//取出从pos位置起,长为len的子串
{char *p;
int k,i;
p=str;k=StrLength(str);
if(pos<1||pos>k||len<0||len>k-pos+1) return ERROR; //参数不合法
sub=new char[len+1];
for(i=pos-1;i<pos+len-1;i++)
*sub++=*(p+i);
*sub='\0';
sub=sub-len;
return OK;
}
void StrCopy(char *&t,char *s)//将子串s复制到t
{ t=new char[StrLength(s)+1];
strcpy(t,s);
}
int StrCompare(char *s,char *t) //比较串s和t
{ return strcmp(s,t);
}
status StrEmpty(char *s) //判断串s是否为空
{
if(!s) return OK; //若空返回OK
else return ERROR; //否则返回ERROR
}
void ClearString(char *&s) //清空串s
{ if(s){
delete(s);
s=NULL;
}
}
/********************出错信息处理***********************************/
void ERRORMESSAGE(char *s) //出错信息处理函数
{
cout<<s<<endl;
exit(1);
}
/***********************建广义表********************************/
void Sever(char *&sub,char *&str){//分离出表头或原子结点的字符串
int i=1,n;char *ch;
n=StrLength(str);
SubString(ch,str,i,1);
if(*ch=='('){ //若第一个字符为(,则或为空表,或为共享部分,返回(
sub=ch;
SubString(str,str,2,n-1); //str为剩余部分
}
else{ //否则返回表头或原子结点的字符串
while(*ch!=')'&&*ch!=','&&*ch!='('&&*ch!='\0') {
i++;
SubString(ch,str,i,1);
}
SubString(sub,str,1,i-1);
SubString(str,str,i,n-i+1);//str为剩余部分
}
}
status GetChar(char *&str,char &ch){ //从字符串头分离一个字符
int n;
if(!str) return ERROR;
n=StrLength(str);
ch=*str; //取出第一个字符
SubString(str,str,2,n-1); //str为剩余部分
return OK;
}
status CreatGList(GList &L,char *&s){ //创建带子表名的广义表
char *ch1,ch2,ch; GList p;status i;
Sever(ch1,s); //取字符串
GetChar(s,ch2); //取下一个字符
if((*ch1=='('||*ch1=='#')&&ch2==')'){ //空表或共享表部分
L=NULL;
if(*ch1=='('){
GetChar(s,ch); //读取下一字符以判断是否仍有未建子表
if(ch==',') return 1; //仍有未建子表返回1
else return 2; //此层次上的子表建完,返回2
}
else return 2;
}
if(!(L=new GLNode)) exit(OVERFLOW);
if(ch2==','||ch2==')'||ch2=='\0'){ //原子结点
L->tag=ATOM;L->atom=ch1;
if(ch2==',') return 1; //仍有未建子表返回1
else return 2; //此层次上的子表建完,返回2
}
if(ch2=='('){ //表结点
L->tag=LIST;
L->ptr.listname=ch1; //listname存放表名
i=CreatGList(L->ptr.hp,s);
p=L;
while(i!=2){ //i!=2时递归建下一子表
p=p->ptr.tp=new GLNode;
p->tag=LIST;p->ptr.listname="#";
i=CreatGList(p->ptr.hp,s);
}
p->ptr.tp=NULL;
GetChar(s,ch);
if(ch==',') return 1; //仍有未建子表返回1
else return 2; //此层次上的子表建完,返回2
}
return FALSE; //字符串错误
}//Creat
/*********************广义表共享*********************************/
GList Get(GList L,int I[]) //根据层次序号查找共享及被共享结点
{ int k,j; GList p;
k=0; p=L;
while(I[k]){
j=1;
while(j<I[k]) {p=p->ptr.tp;j++;}//根据层次序号的第一个数向表尾部走
k++;
if(I[k]) p=p->ptr.hp; //向表头部走
}
return p;
}
void Share(GList &L) //建立共享结构
{ GList p,q;
int I[10];int i; char ch;
do{ i=0;
cout<<"共享子表序号:"<<endl;
cin>>I[i];
while(I[i]) cin>>I[++i];
p=Get(L,I); //p指向共享子表
i=0;
cout<<"被共享子表序号:"<<endl;
cin>>I[i];
while(I[i]) cin>>I[++i];
q=Get(L,I); //q指向被共享子表
p->ptr.hp=q->ptr.hp;p->ptr.tp=q->ptr.tp; //共享
cout<<"another?(y/n)"; //若还有其余共享,输入y
cin>>ch;
}while(ch=='Y'||ch=='y'); //循环控制共享结点个数
}
/***********************打印广义表*****************************/
status PrintGList(GList L,int i)//打印广义表,i为空格数,初始为0
{ GList p,q;int k;
if(!L) {
for(k=0;k<i;k++) cout<<' ';
cout<<"#"<<endl; return OK;
} //打印空表
if(L->tag==ATOM) {
for(k=0;k<i;k++) cout<<' ';
cout<<L->atom<<endl; return OK;
} //打印原子结点
p=L;
for(k=0;k<i;k++) cout<<' ';
cout<<p->ptr.listname<<endl; //打印子表名
while(p){ //打印各个子表
q=p->ptr.hp; //q指向第一个子表
PrintGList(q,i+2); //递归打印第一个子表,空格数增加
p=p->ptr.tp; //指针后移
}//while
return OK;
}//PrintGList