首页 > 其他分享 >10、广义表

10、广义表

时间:2024-09-27 09:02:52浏览次数:1  
标签:10 NULL sub tp GLNode char 广义 gl

1、广义的定义和初始化

#include<stdio.h>
#include<malloc.h>
#include<string.h>
#include<assert.h>
#include<stdlib.h>

#define ATOM_TYPE int


typedef enum {
    HEAD,
    ATOM,
    CHILDLIST
} ElementType;

typedef struct GLNode {
    ElementType tag;  // 标记位, 用于区分原子结点和表节点
    union {
        ATOM_TYPE atom;  // 原子节点的值域
        struct GLNode *hp;  // 表节点的表头指针
    };
    struct GLNode *tp;  // 指向下一个元素节点
} GLNode;

typedef GLNode* GenList;  // 广义表 类型是一种扩展的线性链表

void InitGenList(GenList* gl){
    *gl = NULL;
}

2、广义表的创建

// 分离表头和表尾元素
int separate(char* sub, char* hsub) {
    if (sub[0] == '\0' || strcmp(sub, "()") == 0) {
        hsub[0] = '\0';
        return 1;
    }
    int n = strlen(sub);
    int i = 0, k = 0;  // 用于判断首字符为 ( 的情况
    while (i < n && (sub[i] != ',' || k != 0)) {
        if (sub[i] == '(') k++;
        else if (sub[i] == ')') k--;
        i++;
    }
    if (i < n) {
        strncpy(hsub, sub, i);
        hsub[i] = '\0';
        strcpy((char*)sub, sub + i + 1);
    } else if (k != 0) {
        return 0;
    } else {
        strcpy(hsub, sub);
        sub[0] = '\0';
    }
    return 1;
}



void CreateGenList(GenList* gl,char* str){
    /*
    将广义表就看成两部分:表头(广义表第一个元素) 表尾(广义表除第一个元素的其他元素)
    */
    //先去除最外层括号 
    int n = strlen(str);
    //用于存储去掉最外层括号的str
    char* sub = (char*)malloc(sizeof(char) * (n-2));
    //用于存储表头元素 
    char* hsub = (char*)malloc(sizeof(char) * (n-2));
    assert(sub != NULL && hsub != NULL);
    strncpy(sub, str + 1,n - 1);
    sub[n - 2] = '\0';
    
    if(*gl == NULL){
        //说明当前是表头节点 
        *gl = (GLNode*)malloc(sizeof(GLNode));
        assert(*gl != NULL); 
        (*gl)->tag = HEAD;
        (*gl)->hp = (*gl)->tp = NULL;
    }
    //采用尾插法 
    GLNode *p = *gl;
    while(strlen(sub) != 0){
        p = p->tp = (GLNode*)malloc(sizeof(GLNode));
        assert(p != NULL);
        //填充数据
        p->hp = p->tp = NULL;
        
        //"1,2,3" ==> hsub="1", sub="2,3"
        //"(1,2),3,4" ==> hsub="(1,2)" sub="3,4" 
        if(separate(sub,hsub)){
            if(hsub[0] == '('){
                //说明分离出来的元素是个子表
                p->tag = CHILDLIST;
                CreateGenList(&p->hp,hsub);                
            } else {
                p->tag = ATOM;
                p->atom = atoi(hsub);
            }
        } 
    }
}

3、广义表的其他方法实现

void showGenList(GenList gl) {
    GLNode* p = gl->tp;
    printf("(");
    while (p != NULL) {
        if (p->tag == ATOM) {
            printf("%d", p->atom);
        } else if (p->tag == CHILDLIST) {
            showGenList(p->hp);
        }
        // 检查下一个节点是否存在,如果存在则打印逗号
        if (p->tp != NULL) {
            printf(",");
        }
        p = p->tp;
    }
    printf(")");
}

// 求广义表的长度 
int length(GenList gl){
    int len = 0;
    while(gl->tp != NULL){
        len++;
        gl = gl->tp;
    }
    return len;
} 
int GenListDepth(GenList gl){
    if(gl->tp == NULL)
        return 1;
    //指向广义表第一个节点 
    GLNode *p = gl->tp;
    int maxDepth = 0;
    int dep;
    while(p != NULL){
        if(p->tag == CHILDLIST) {
            // 传入广义表子表的 第一个节点 
            dep = GenListDepth(p->hp->tp);
            if(dep > maxDepth){
                maxDepth = dep;
            }    
        }
        p = p->tp;
    }
    return maxDepth + 1;
}


void freeGenList(GenList gl) {
    if (gl == NULL) return;
    GLNode* p = gl->tp;
    while (p != NULL) {
        if (p->tag == CHILDLIST) {
            freeGenList(p->hp);
        }
        GLNode* next = p->tp;
        free(p);
        p = next;
    }
    free(gl);
}

int main(){
    GenList gl;
    InitGenList(&gl);
    char* ga = "(1,2,3)";
    char* gb = "(1,(2,3))";
    char* gc = "(1,(2),3)";
    char* gd = "((1,2),3)";
    char* ge = "((1,2,3))";
    char* gf = "()";
    char* gg = "(1,(2,(3,4)),5)";
    
    CreateGenList(&gl,gg);
    showGenList(gl); 
    printf("\nLength: %d",length(gl));
    printf("\nDepth: %d",GenListDepth(gl));
    freeGenList(gl);  // 释放广义表占用的内存
    return 0;
} 

 

标签:10,NULL,sub,tp,GLNode,char,广义,gl
From: https://www.cnblogs.com/xpp3/p/18434957

相关文章

  • 《HelloGitHub》第 102 期
    兴趣是最好的老师,HelloGitHub让你对编程感兴趣!简介HelloGitHub分享GitHub上有趣、入门级的开源项目。github.com/521xueweihan/HelloGitHub这里有实战项目、入门教程、黑科技、开源书籍、大厂开源项目等,涵盖多种编程语言Python、Java、Go、C/C++、Swift...让你在短......
  • P10681 COTS/CETS 2024 奇偶矩阵 Tablica
    P10681COTS/CETS2024奇偶矩阵Tablica来自qnqfff大佬的梦幻dp。约定二元组\((n,m)\)表示一个\(n\)行\(m\)列的矩形。不添加说明的子问题,限制与题面一致。思路先考虑放最后一行,发现你填的位置经过变换后可以得到其他的结果,也就是说只要乘上变换的方案数就可以任......
  • 戴尔笔记本怎么重装系统_戴尔笔记本重装系统win10教程(支持新旧机型安装)
         戴尔笔记本怎么重装系统?戴尔笔记本这几年默认预装win10家庭版和win11家庭版。有的用户用上了预装win11家庭版的戴尔笔记本,使用一段时间依然不习惯,于是想退回win10。但不知道怎么重装win10,这几年的戴尔笔记本建议采用U盘方式安装系统比较保险,在线安装的话可能触发......
  • 易优CMS网站SQLSTATE[42S22]: Column not found: 1054 Unknown column 'a. province_i
    当你遇到“SQLSTATE[42S22]:Columnnotfound:1054Unknowncolumn'a.province_id'in'whereclause'”的错误提示时,通常是因为查询中引用了一个不存在的列。以下是一些具体的解决步骤:步骤1:检查数据库表结构确认表结构确认数据库表中是否存在 province_id 列。使用......
  • GAMES101(作业7)
     作业七题目:实现pathTracing,仅修改castRay(constRayray,intdepth)函数,在其中实现PathTracing算法代码框架://OBJ-loader模型加载库 global:全局变量/函数 vector:Vector3f,Vector2f类floatnorm(){returnstd::sqrt(x*x+y*y+z*z);}/*向量长度......
  • 1023 - 判断素数
    题目描述任意输入一个整数,判断它是否为素数。是的话输出T,不是的话输出F。质数(primenumber)又称素数,质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数。输入输入只有一行,包括1个整数。(1≤n≤10^9)输出输出只有一行。样例输入57输出F输入7......
  • Python从0到100(五十八):机器学习-随机森林及对复杂数据集分类
    随机森林通过构建多个决策树来完成分类或回归任务。随机森林的核⼼思想是通过多个弱学习器(决策树)的集成来构建⼀个强学习器,从⽽提⾼模型的泛化能⼒和稳定性。1.基本原理随机森林的基本原理如下:从训练集中随机抽取⼀定数量的样本(有放回抽样),构建⼀个决策树(称为⾃助采样法或......
  • 嵌入式项目:STM32平衡车详解 (基础知识篇) (基于STM32F103C8T6)
    前言:本文是基于B站草履虫编写的平衡车相关内容,包括模块和基础知识,结合代码进行讲解,将知识进行汇总(由于本篇内容较长,请结合目录使用)注:基于开源精神,本文仅供学习参考目录前言:本文是基于B站草履虫编写的平衡车相关内容,包括模块和基础知识,结合代码进行讲解,将知识进行汇总......
  • 技术人的福音!深度对比10款工业项目管理软件,为你的项目保驾护航
    市面上主流的10款工业项目管理系统推荐:PingCode、Worktile、Smartsheet、Wrike、ProofHub、ZohoProjects、ClickUp、致远OA、用友协同云、金蝶EAS。在选择项目管理系统时,许多小型企业和初创公司常常面临着难以决策的痛点:如何找到既能提高团队效率又易于操作的工具呢?一个合......
  • CF1063E Lasers and Mirrors题解
    一道很好的手玩题,被薄纱了。首先判掉\(\foralli,p_i=i\)的情况(显然是\(n\))然后考虑按照\(p_i\)连边,先构造每一个环的方案。发现可以简单放置两面镜子使得\(i\)射到\(p_i\),而且只要从高到底构造,一定不会产生影响。但是每一个环的最后一个点很特殊,因为第1个点下面放置了让第1个......