noj14求广义表深度

本文深入介绍了广义表的概念,包括原子、子表、表头和表尾,并通过示例解释了其结构。同时,提供了C语言实现广义表的创建方法,包括两种不同的存储结构。此外,还讨论了广义表的深度计算,给出了相应的递归算法。文章旨在帮助初学者掌握广义表的理论与实践操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
广义表理论上很好理解,但是我感觉对我来说上手还有点困难(还是太菜)。
先看广义表的一些定义吧

1 )什么是广义表
广义表,又称列表,也是一种线性存储结构,既可以存储不可再分的元素,也可以存储广义表,记作:LS = (a1,a2,…,an),其中,LS 代表广义表的名称,an 表示广义表存储的数据,广义表中每个 ai 既可以代表单个元素,也可以代表另一个广义表。
2 )广义表的原子和子表
广义表中存储的单个元素称为 “原子”,而存储的广义表称为 “子表”。
例如 :广义表 LS = {1,{1,2,3}},则此广义表的构成 :广义表 LS 存储了一个原子 1 和子表 {1,2,3}。
广义表存储数据的一些常用形式:
A = ():A 表示一个广义表,只不过表是空的。
B = (e):广义表 B 中只有一个原子 e。
C = (a,(b,c,d)) :广义表 C 中有两个元素,原子 a 和子表 (b,c,d)。
D = (A,B,C):广义表 D 中存有 3 个子表,分别是A、B和C。这种表示方式等同于 D = ((),(e),(b,c,d)) 。
E = (a,E):广义表 E 中有两个元素,原子 a 和它本身。这是一个递归广义表,等同于:E = (a,(a,(a,…)))。
3 ) 广义表的表头和表尾
当广义表不是空表时,称第一个数据(原子或子表)为"表头",剩下的数据构成的新广义表为"表尾"。
除非广义表为空表,否则广义表一定具有表头和表尾,且广义表的表尾一定是一个广义表。
具体定义详见原文链接:https://blog.youkuaiyun.com/weixin_44289254/article/details/123693094

再看题上,其实本人感觉难的点其实是输入与创建广义表
我也是看着大佬的照猫画虎来的

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef enum {ATOM,LIST}ElemTag;//ATOM为0,LIST为1

//广义表的头尾链表存储结构
typedef struct GLnode
{
    ElemTag tag;//标志
    union
    {
         char atom;//原子节点
         struct
        {
            struct GLnode *head;//表节点
            struct GLnode *tail;
        }ptr;//头节点,尾节点
    }un;
}GLnode,*GList;

//广义表的同层节点链存储结构
typedef struct GGlnode
{
    ElemTag tag;
    union
    {
        char atom;
        struct GGlnode *head;
    }un;
    struct GGlnode *tail;
}GGlnode,*GGlist;

//创建原子节点
void CreateAtom(GList c,char ch)
{
    c->tag=ATOM;
    c->un.atom=ch;
}

//创建子表节点
void CreateList(GList c)
{
    c->tag=LIST;
    c->un.ptr.head=NULL;
    c->un.ptr.tail=NULL;
}

//定位函数,让广义表回到输入应该属于的层数上来
char* Location(char *str)
{
    if(str[0]=='\0') return 0;//无字符情况
    int flag=1,len=strlen(str);//flag标志()的情况
    int i;
    for(i = 0; i < len; i++) {
        if (str[i] == '(') {
            flag++;
        }
        if (str[i] == ')') {
            flag--;
        }
        if (flag == 0) {
            break;
        }
    }
    if (str[i+1] == '\0') {
        return 0;
    }
    return (str+i+1);//指向下一个字符
}

//创建广义表
void CreateGlist(GList s,char *str)
{
    if(str[0] == '(')//下一个为字母
    {
        CreateList(s);//子表
        s->un.ptr.head=(GList)malloc(sizeof(GLnode));//开辟空间
        str=str+1;//从(移动
        CreateGlist(s->un.ptr.head,str);//递归写入
        str=Location(str);//下一个
        if(str==0)
        {
            return;
        }
    }
    else if( str[0]==')')
    {
         return;//用于递归
    }
    else if(str[0]==',')//下一个为字母
    {
        s->un.ptr.tail=(GList)malloc(sizeof(GLnode));//开辟空间
        str = str + 1;
        CreateGlist(s->un.ptr.tail,str);//递归写入
        return;
    }
    else//此时为字母
    {
        CreateList(s);//子表
        s->un.ptr.head=(GList)malloc(sizeof(GLnode));
        CreateAtom(s->un.ptr.head,str[0]);//原子节点
        str=str+1;
    }
    //下一个字符
    if(str[0] == ')') return;
    else if(str[0]==',')
    {
        s->un.ptr.tail=(GList)malloc(sizeof(GLnode));
        str=str+1;
        CreateGlist(s->un.ptr.tail,str);
        return;
    }
}
//同层节点链存储结构创建广义表
void CCreateGlist(GGlist s,char *str)
{
    if(str[0]=='(')
    {
        s->tag=LIST;
        s->un.head=(GGlist)malloc(sizeof(GGlnode));
        str=str+1;
        CCreateGlist(s->un.head,str);
        str=Location(str);
        if (str == 0) {
            return;
        }
    }
    else if(str[0]==')')
    {
        s=NULL;
        return;
    }
    else if(str[0]==',')
    {
        s->tail=(GGlist)malloc(sizeof(GGlnode));
        str=str+1;
        CCreateGlist(s->tail,str);
         return;
    }
    else//字母
    {
        s->tag=ATOM;
        s->un.atom=str[0];
        str=str+1;
    }
    if(str[0]==')')
    {
        s->tail=NULL;
        return;
    }
    else if(str[0]==',')
    {
        s->tail=(GGlist)malloc(sizeof(GGlnode));
        str=str+1;
        CCreateGlist(s->tail,str);
         return;
    }
}
//求广义表深度
int Depth(GList s)
{
    int temp=0,max=0;
    GList p;
    p=s;
    if(s==NULL) return 1;//空表深度为
    if(s->tag==ATOM) return 0;//原子节点深度为0
    while(p!=NULL)
    {
        temp=Depth(p->un.ptr.head);
        if(temp>max)
        {
            max=temp;
        }
        p=p->un.ptr.tail;
    }
    return(max+1);//表的深度等于最深子表加一
}
//同层节点链存储结构创建广义表
//求深度
int DDepth(GGlist s)
{
    int temp=0,max=0;
    GGlist p;
    p=s->un.head;
    if(s->tag==ATOM) return 0;
    if(p==NULL) return 1;
    while(p!=NULL)
    {
        if(p->tag==LIST)
        {
            temp=DDepth(p);
        }
        if(temp>max)
        {
            max=temp;
        }
        p=p->tail;
    }
    return (max+1);
}
int main()
{
   int dep,ddep;
   char *str;
   str=(char *) malloc (sizeof(char));
   GLnode a;
   GGlnode b;
   scanf("%s",str);
   CreateGlist(&a,str+1);
   CCreateGlist(&b,str);
   dep=Depth(&a);
   ddep=DDepth(&b);
   printf("%d\n%d",dep,ddep);
    return 0;
}

大神连接:https://blog.youkuaiyun.com/weixin_53068269/article/details/115681434

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值