广义表 GL 采用头尾表示存储,设计一个算法,求 GL 的长度。
源代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct GLNode{
int tag;//公共部分,用于区分原子节点和表结点
union{
char atom;//atom原子结点的值域
struct{
struct GLNode * hp,*tp;//hp指向表头,tp指向表尾
}ptr;//ptr是表结点的指针域
};
}*Glist;//广义表类型
Glist creatGlist(Glist C){
C=(Glist)malloc(sizeof(Glist));//为广义表C开辟空间
C->tag=1;
C->ptr.hp=(Glist)malloc(sizeof(Glist));
C->ptr.hp->tag=0;
C->ptr.hp->atom='a';//将a赋值到原子节点中
C->ptr.tp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->tag=1;
C->ptr.tp->ptr.hp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.tp=NULL; //表尾子表(b,c,d),是一个整体
C->ptr.tp->ptr.hp->tag=1;
C->ptr.tp->ptr.hp->ptr.hp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.hp->tag=0;
C->ptr.tp->ptr.hp->ptr.hp->atom='b'; //开始存放下一个数据元素(b,c,d),表头为‘b’,表尾为(c,d)
C->ptr.tp->ptr.hp->ptr.tp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.tp->tag=1;
C->ptr.tp->ptr.hp->ptr.tp->ptr.hp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag=0;
C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom='c';//存放子表(c,d),表头为c,表尾为d
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->tag=1;
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp=(Glist)malloc(sizeof(Glist));
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->tag=0;
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.hp->atom='d'; //存放表尾d //存放表尾d
C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp=NULL;
return C;
}
int GlistLength(Glist C){
int Number=0;
Glist P=C;
while(P){
Number++;
P=P->ptr.tp;
}
return Number;
}
int main(){
Glist C = creatGlist(C);
printf("广义表的长度为:%d",GlistLength(C));
return 0;
}
可以自行输入广义表求其长度
源代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {ATOM, LIST}ElemTag; //ATOM==0 原子, LIST==1 子表
struct GLNode
{
ElemTag tag; //标识域,用于区分原子结点和表结点
union
{
char atom; //值域
struct GLNode *hp; //hp指向表头
};
struct GLNode *tp; //tp指向表尾
};
typedef struct GLNode GList;
void Getsubs();//求取广义表的子串Subs
GList *GListCreate();//创建广义表
void GListPrint();//打印广义表
int GListLength();//返回广义的长度
void Getsubs(char str[], char hstr[])//求取广义表的子串Subs
{
int i=0;
int j=0;
int k=0; //用来记录没有匹配的左括号数
int r=0;
char s[100];
while(str[i]&&(str[i]!=','||k))
{
if(str[i]=='(')
k++;
else if(str[i]==')')
k--; //记录左括号数的操作
if(str[i]!=','||str[i]==','&&k)
{
hstr[j]=str[i];
i++;
j++;
}
}
hstr[j]='\0';
if(str[i]==',')
i++;
while(str[i])
{
s[r]=str[i];
r++;
i++;
}
s[r]='\0';
strcpy(str,s);
}
//创建广义表
GList *GListCreate(char str[])
{
GList *G;
char subs[100];
char hstr[100];
GList *q;
int len=strlen(str);
if(len==0||!strcmp(str,"()"))
G=NULL;
else if(len==1) //原子结点的情况
{
G=(GList *)malloc(sizeof(GList));
if(!G)
{
printf("申请空间失败!");
exit(0);
}
G->tag = ATOM;
G->atom = *str;
G->tp = NULL;
}
else
{
GList *p;
G=(GList *)malloc(sizeof(GList));
if(!G)
{
printf("申请空间失败!");
exit(0);
}
G->tag = LIST;
p=G;
str++;
strncpy(subs,str,len-2); //去掉最外面的()
subs[len-2]='\0';
while(len>0)
{
GList *r;
Getsubs(subs,hstr); //将subs分开为表头hstr和表尾subs
r=GListCreate(hstr); //生成表头的广义表
p->hp=r;
q=p;
len=strlen(subs);
if(len>0)
{
p=(GList *)malloc(sizeof(GList));
if(!G)
{
printf("申请空间失败!");
exit(0);
}
p->tag = LIST;
q->tp=p;
}
}
q->tp=NULL;
}
return G;
}
//打印广义表
void GListPrint(GList *G)
{
GList *q,*p;
printf("(");
while(G)
{
p=G->hp;
q=G->tp;
if(p&&q&&!p->tag) //p为原子结点,并且有后续结点
{
printf("%c,",p->atom);
p=q->hp;
q=q->tp;
}
if(p&&!p->tag) //p为原子结点,并且没有后续结点
{
printf("%c",p->atom);
break;
}
else
{
if(!p)
printf("()"); //p为空表
else
GListPrint(p);
if(q)
printf(","); //还存在着后续的结点
G=q;
}
}
printf(")");
}
int GListLength(GList *C){//返回广义的长度
int number=0;
GList *p=C;
while(p){
number++;
p=p->tp;
}
return number;
}
int main()
{
int n;
char *s;
GList *G;
printf("请输入广义表的字符数:\n");
scanf("%d",&n);
printf("请输入广义表:\n");
s=(char *)malloc(n*sizeof(char));
scanf("%s",s);
G=GListCreate(s);
printf("所输入的广义表为:\n");
GListPrint(G);
printf("\n");
int number=GListLength(G);
printf("广义表的长度为:%d",number);
return 0;
}