广义表模板

typedef enum
{
    ATOM,LIST//注意这没分号
}ElemTag;
typedef struct GLnode
{
    ElemTag tag;
    union
    {
        char atom;    //char 表示原子型,struct 表示表
        struct
        {
            struct GLnode *head,*tail;
        }htp;
    }atom_htp;

}GLNode,*GList;


//广义表求其深度


int Depth(GLNode* L)
{
    int d;
    int maxn=0;
    GLNode *s;
    if(L==NULL)
    return 1;  //空表的深度为1;
    if(L->tag==ATOM)
    return 0; //原子表的深度为0;
    s=L;
    while(s!=NULL)  //同一层的每个都到头
    {
        d=Depth(s->atom_htp.htp.head);
        if(d>maxn)
        maxn=d;
        s=s->atom_htp.htp.tail;
    }
    return (maxn+1);

}


void getsubs(char str[],char hstr[])  //删除括号的的情况:1.左括号,2.数字
{
    int i=0,j=0,k=0,r=0;
    char s[100000];
    while(str[i]&&(str[i]!=','||k)) //到字符数组最尾或(str[i]==','且括号左右括号抵消)跳出循环
    {                               //如(),或直接,这两种情况。
        if(str[i]=='(')             //   12 3 str[3]跳出循环
        k++;
        else if(str[i]==')')
        k--;
        if(str[i]!=','||(str[i]==','&&k))//不等于','就只有'(',')','a'这三种情况
        {                              //str[i]==','&&k就是说这个','是在括号内的合法的',';
            hstr[j]=str[i];
            i++;
            j++;
        }
    }
    hstr[j]='\0';  //所以hstr[]存的是当前的头,注意,由上面的if可知,hstr[]不带逗号。
    if(str[i]==',') //因为可能是到终点才结束的,所以这if才有意义
    i++;
    while(str[i])
    {
        s[r]=str[i];  //s[r]存的是当前的尾。
        r++;
        i++;
    }
    s[r]='\0';
    strcpy(str,s);//subs变成当前尾。
    return;

}

//广义表的创建


GList CreateGList(char str[]) //还是为了->个符号的操作。//L是第二层了。
{
   GLNode *L;
   char subs[100000];              //是只有子女,没有兄弟的广义表
   char hstr[100000];
   GLNode* q;                      //头是指子女,尾是指兄弟
   int len=strlen(str);
   if(len==0||strcmp(str,"()")==0) //空表的两种情况
   L=NULL;
   else if(len==1)     //原子结点的情况。
   {
       if(!(L=(GLNode *)malloc(sizeof(GLNode)))) //广义表外面必须要有括号,没括号就一种原子结点的情况。
       exit(0);                                  //L不是总体,而是第一个兄弟
       L->tag=ATOM;                              //第一个兄弟是相对同层括号而言的
       L->atom_htp.atom=str[0];
       L->atom_htp.htp.tail=NULL;//感觉有必要添加
   }
   else
   {
       GLNode *p;    //p是用来 创建空间的,q是用来纪录当前创建位置的
       if(!(L=(GLNode *)malloc(sizeof(GLNode))))
       exit(0);
       L->tag=LIST;//定L为表结点
       p=L;   //储存头结点的地址
       str++; //str的地址变成str[1]的地址,也就删掉了第一个左括号
       strncpy(subs,str,len-2);   //删右括号,
       subs[len-2]='\0';
       while(len>0)  //初始的len是最开始str的len
       {
           GLNode* r;
           getsubs(subs,hstr);
           r=CreateGList(hstr);//因为是递归构建,所以函数应该返回地址,然都公用一个地址就弄乱了
           p->atom_htp.htp.head=r;//创建递归回来之后才将下连接到上。
           q=p;
           len=strlen(subs);//第二次测len是裁剪之后,因为调用了getsubs(subs,hstr)后,subs被剪裁了
           if(len>0) //如果不为空,则继续创建同层次的表。如果为空,同层次接NULL,并跳出循环。
           {
               if(!(p=(GLNode*)malloc(sizeof(GLNode))))
               exit(0);
               p->tag=LIST;
               q->atom_htp.htp.tail=p;
           }
       }
        p->atom_htp.htp.tail=NULL;
   }
   return L;

}



int main()
{
  GLNode* L;
  char str[100000];
  scanf("%s",str);
  L=CreateGList(str);
  printf("%d\n",Depth(L));
  printf("%d\n",Depth(L));
  return 0;
}

猜你喜欢

转载自blog.csdn.net/xigongdali/article/details/80774246