P141 例7-2 设广义表采用头链和尾链存储结构,要求:
(1)编写按广义表中原子项所在层次输出所有原子项和广义表输出函数。
(2)设广义表L=(((a,b,c),d),e,(f)),编写一个主函数测试输出函数。
头文件:GList.h
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char DataType;
typedef struct GListNode
{
int tag;
union
{
DataType atom;
struct
{
struct GListNode *head;
struct GListNode *tail;
}subList;
}val;
}GLNode;
void DecomposeStr(char str[],char hstr[])
{
int i,j,tag,n=(int)strlen(str);
char ch;
ch=str[0];tag=0;
for(i=0;i<n-1;i++)
{
if(str[i]==','&&tag==1)
break;
ch=str[i];
if(ch=='(')
tag++;
if(ch==')')
tag--;
}
if(i<=n-1&&str[i]==',')
{
for(j=0;j<i-1;j++)
hstr[j]=str[j+1];
hstr[j]='\0';
if(str[i]==',')
i++;
str[0]='(';
for(j=1;i<=n-2;i++,j++)
str[j]=str[i];
str[j]=')';
str[++j]='\0';
}
else
{
str++;
strcpy(hstr,str);
hstr[n-2]='\0';
str--;
strcpy(str,"()");
}
}
GLNode *CreatGList(char str[])
{
GLNode *h;
char hstr[200];
int len=(int)strlen(str);
if(strcmp(str,"()")==0)
h=NULL;
else if(len==1)
{
h=(GLNode*)malloc(sizeof(GLNode));
h->tag=0;
h->val.atom=str[0];
}
else
{
h=(GLNode*)malloc(sizeof(GLNode));
h->tag=1;
DecomposeStr(str,hstr);
h->val.subList.head=CreatGList(hstr);
if(strcmp(str,"()")!=0)
h->val.subList.tail=CreatGList(str);
else
h->val.subList.tail=NULL;
}
return h;
}
int GListDepth(GLNode *h)
{
int max,dep;
GLNode *pre;
if(h==NULL)
return 1;
if(h->tag==0)
return 0;
pre=h;
for(max=0;pre!=NULL;pre=pre->val.subList.tail)
{
dep=GListDepth(pre->val.subList.head);
if(dep>max)
max=dep;
}
return max+1;
}
int GListLength(GLNode *h)
{
int number=0;
GLNode *p;
for(p=h;p!=NULL;p=p->val.subList.tail)
number++;
return number;
}
int GListAtomNum(GLNode *h)
{
if(h==NULL)
return 0;
else
{
if(h->tag==0)
return 1;
else
return GListAtomNum(h->val.subList.head)+GListAtomNum(h->val.subList.tail);
}
}
GLNode *GListSearch(GLNode *h,DataType x)
{
GLNode *p;
if(h==NULL)
return NULL;
if(h->tag==0&&h->val.atom==x)
return h;
if(h->tag==1&&h->val.subList.head!=NULL)
{
p=GListSearch(h->val.subList.head,x);
if(p!=NULL)
return p;
}
if(h->tag==1&&h->val.subList.tail!=NULL)
{
p=GListSearch(h->val.subList.tail,x);
if(p!=NULL)
return p;
}
return NULL;
}
void DestroyGList(GLNode *h)
{
if(h==NULL)
return;
if(h->tag==1&&h->val.subList.head!=NULL)
DestroyGList(h->val.subList.head);
if(h->tag==1&&h->val.subList.tail!=NULL)
DestroyGList(h->val.subList.tail);
free(h);
}
源文件:例7-2.c
#include"GList.h"
void GListPrint(GLNode *h,int n)
{
int i;
GLNode *p;
if(h==NULL)
return;
if(h->tag==0)
{
for(i=0;i<n;i++)
printf(" ");
printf("%c\n",h->val.atom);
return;
}
for(p=h;p!=NULL;p=p->val.subList.tail)
GListPrint(p->val.subList.head,n+1);
}
int main()
{
char str[]="(((a,b,c),d),e,(f))";
GLNode *p;
int n=0;
p=CreatGList(str);
GListPrint(p,n);
DestroyGList(p);
return 0;
}
在VS2019下,需将头文件的strcpy做一些修改,所以在VS2019下头文件GList.h为:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef char DataType;
typedef struct GListNode
{
int tag;
union
{
DataType atom;
struct
{
struct GListNode* head;
struct GListNode* tail;
}subList;
}val;
}GLNode;
void DecomposeStr(char str[], char hstr[])
{
int i, j, tag, n = (int)strlen(str);
char ch;
ch = str[0]; tag = 0;
for (i = 0; i < n - 1; i++)
{
if (str[i] == ',' && tag == 1)
break;
ch = str[i];
if (ch == '(')
tag++;
if (ch == ')')
tag--;
}
if (i <= n - 1 && str[i] == ',')
{
for (j = 0; j < i - 1; j++)
hstr[j] = str[j + 1];
hstr[j] = '\0';
if (str[i] == ',')
i++;
str[0] = '(';
for (j = 1; i <= n - 2; i++, j++)
str[j] = str[i];
str[j] = ')';
str[++j] = '\0';
}
else
{
str++;
strcpy_s(hstr, strlen(str) + 1, str);
hstr[n - 2] = '\0';
str--;
strcpy_s(str, strlen("()") + 1, "()");
}
}
GLNode* CreatGList(char str[])
{
GLNode* h;
char hstr[200];
int len = (int)strlen(str);
if (strcmp(str, "()") == 0)
h = NULL;
else if (len == 1)
{
h = (GLNode*)malloc(sizeof(GLNode));
h->tag = 0;
h->val.atom = str[0];
}
else
{
h = (GLNode*)malloc(sizeof(GLNode));
h->tag = 1;
DecomposeStr(str, hstr);
h->val.subList.head = CreatGList(hstr);
if (strcmp(str, "()") != 0)
h->val.subList.tail = CreatGList(str);
else
h->val.subList.tail = NULL;
}
return h;
}
int GListDepth(GLNode* h)
{
int max, dep;
GLNode* pre;
if (h == NULL)
return 1;
if (h->tag == 0)
return 0;
pre = h;
for (max = 0; pre != NULL; pre = pre->val.subList.tail)
{
dep = GListDepth(pre->val.subList.head);
if (dep > max)
max = dep;
}
return max + 1;
}
int GListLength(GLNode* h)
{
int number = 0;
GLNode* p;
for (p = h; p != NULL; p = p->val.subList.tail)
number++;
return number;
}
int GListAtomNum(GLNode* h)
{
if (h == NULL)
return 0;
else
{
if (h->tag == 0)
return 1;
else
return GListAtomNum(h->val.subList.head) + GListAtomNum(h->val.subList.tail);
}
}
GLNode* GListSearch(GLNode* h, DataType x)
{
GLNode* p;
if (h == NULL)
return NULL;
if (h->tag == 0 && h->val.atom == x)
return h;
if (h->tag == 1 && h->val.subList.head != NULL)
{
p = GListSearch(h->val.subList.head, x);
if (p != NULL)
return p;
}
if (h->tag == 1 && h->val.subList.tail != NULL)
{
p = GListSearch(h->val.subList.tail, x);
if (p != NULL)
return p;
}
return NULL;
}
void DestroyGList(GLNode* h)
{
if (h == NULL)
return;
if (h->tag == 1 && h->val.subList.head != NULL)
DestroyGList(h->val.subList.head);
if (h->tag == 1 && h->val.subList.tail != NULL)
DestroyGList(h->val.subList.tail);
free(h);
}