数据结构29:广义表的长度和深度

广义表的长度

通过前一节对广义表的介绍,例子中给出了几个广义表的长度。例如:空表的长度为 0,只含有一个原子的广义表长度为 1,等等。

广义表的长度指的是广义表中数据元素的数量。这里需要指明的是,一个广义表中,一个原子算做是一个元素,一个子表也只算做一个元素。

在 LS = (a1,a2,…,an) 中,ai表示原子或者子表, LS 的长度为 n。

广义表的深度

广义表的深度,指的是广义表中括号的重数。
例如:C=(a,(b,c,d)):


图1 广义表C的深度

图1中,从前往后数左括号的数量就是广义表C的深度,为2;也可以从右往左数右括号的数量(红色)。

求解广义表的深度

求广义表的深度之前,首先要将广义表用某个数据结构表示出来,在前边学习广义表时,介绍了两种表示广义表的方法。这里采用的方法是第一种。

表示结构为:(拿广义表C为例)

广义表第一节中有具体实现的代码,实现函数为:creatGlist(Glist C)。这里不再过多介绍。

求广义表深度的算法用到的是递归的思想,解题思路是:

  1. 从广义表 C 的开头位置,一次遍历表中每个数据元素:当遍历对象为原子时,返回原子的深度为 0 ;遍历对象为表 C 的子表时,继续遍历子表中的数据元素。
  2. 递归的出口有两个:当遍历对象为原子时,返回 0 ;遍历对象为空表时,返回 1 (空表的深度为 1 );
  3. 设置一个初始值为 0 的整形变量 max ,用 max 和遍历过程中返回的整形数值进行比较,取大的那一个,知道程序结束,max + 1就是广义表的深度。

实现代码为:

int GlistDepth(Glist C){
  //如果表C为空表时,直接返回长度1;
  if (!C)   {
    return 1;
  }
  //如果表C为原子时,直接返回0;
  if (C->tag == 0)   {
    return 0;
  }
  int max = 0;  //设置表C的初始长度为0;
  for (Glist pp=C; pp; pp=pp->ptr.tp)   {
    int dep = GlistDepth(pp->ptr.hp);
    if (dep>max)     {
      max = dep;  //每次找到表中遍历到深度最大的表,并用max记录
    }
  }
  //程序运行至此处,表明广义表不是空表,由于原子返回的是0,而实际长度是1,所以,此处要+1;
  return max+1;
}

完整代码演示

#include <stdio.h>
#include <stdlib.h>
typedef struct GLNode{
  int tag;  //标志域
  union  {
    char atom;  //原子结点的值域
    struct    {
      struct GLNode *hp, *tp;
    }ptr;  //子表结点的指针域,hp指向表头;tp指向表尾
  };
}*Glist, GNode;
Glist creatGlist(Glist C){
  //广义表C
  C=(Glist)malloc(sizeof(GNode));
  C->tag = 1;
  //表头原子‘a’
  C->ptr.hp = (Glist)malloc(sizeof(GNode));
  C->ptr.hp->tag = 0;
  C->ptr.hp->atom = ‘a‘;
  //表尾子表(b,c,d),是一个整体
  C->ptr.tp = (Glist)malloc(sizeof(GNode));
  C->ptr.tp->tag = 1;
  C->ptr.tp->ptr.hp = (Glist)malloc(sizeof(GNode));
  C->ptr.tp->ptr.tp = NULL;
  //开始存放下一个数据元素(b,c,d),表头为‘b’,表尾为(c,d)
  C->ptr.tp->ptr.hp->tag = 1;
  C->ptr.tp->ptr.hp->ptr.hp = (Glist)malloc(sizeof(GNode));
  C->ptr.tp->ptr.hp->ptr.hp->tag = 0;
  C->ptr.tp->ptr.hp->ptr.hp->atom = ‘b‘;
  C->ptr.tp->ptr.hp->ptr.tp = (Glist)malloc(sizeof(GNode));
  //存放子表(c,d),表头为c,表尾为d
  C->ptr.tp->ptr.hp->ptr.tp->tag = 1;
  C->ptr.tp->ptr.hp->ptr.tp->ptr.hp = (Glist)malloc(sizeof(GNode));
  C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->tag = 0;
  C->ptr.tp->ptr.hp->ptr.tp->ptr.hp->atom = ‘c‘;
  C->ptr.tp->ptr.hp->ptr.tp->ptr.tp = (Glist)malloc(sizeof(GNode));
  //存放表尾d
  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(GNode));
  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‘;
  C->ptr.tp->ptr.hp->ptr.tp->ptr.tp->ptr.tp = NULL;
  return C;
}
//求广义表的深度,递归调用
int GlistDepth(Glist C){
  if (!C)   {
    return 1;
  }
  if (C->tag == 0)   {
    return 0;
  }
  int max = 0;
  for (Glist pp=C; pp; pp=pp->ptr.tp)   {
    int dep = GlistDepth(pp->ptr.hp);
    if (dep>max)     {
      max = dep;
    }
  }
  return max+1;
}
int main(int argc, const char *argv[]){
  Glist C = creatGlist(C);
  printf("%d", GlistDepth(C));
  return 0;
}
运行结果:
2

原文地址:https://www.cnblogs.com/ciyeer/p/9040533.html

时间: 2024-11-08 08:25:56

数据结构29:广义表的长度和深度的相关文章

javascript实现数据结构:广义表

原文:javascript实现数据结构:广义表  广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an) LS是广义表的名称,n是它的长度,ai可以是单个元素,也可以是广义表,分别称为广义表LS的原子和子表.习惯上,用大写字母表示广义表的名称,小写字母表示原子.当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2, a3, ..., an)是LS的表尾. 下面列举一些广义表的例

数据结构之广义表

#include<stdio.h> //广义表的头尾链表存储结构 typedef int AtomType; typedef enum NodeType{ATOM,LIST}ElemTag;//ATOM表示原子结点,LIST表示表节点 typedef struct GLNode{ ElemTag tag; union{ AtomType atom; struct List{ struct GLNode* hp,*tp; } htp; }atom_htp; }GLNode,*GList; //求

数据结构 c++ 广义表

// CTest.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> #include <string.h> #include <stdio.h> using namespace std; typedef char ElemType; struct GLNode{ bool tag; //标志位 union{ //值域或子表的表头指针域 ElemType data; GLNo

【数据结构】广义表的默认成员函数、深度、大小、打印

广义表的定义: 广义表是非线性的结构,是n个元素的有限序列. 举例:A=(a,b,(c,d)) 我们先定义它的结构: (1)它有三种节点,头节点.值节点.子表节点. (2)两种指向下一节点的指针:指向下一值值节点的指针_next,指向子表节点的指针_sublink. (3)_next与_sublink只有一种 enum Type//用枚举形式来定义广义表中三种节点类型 {     HEAD, //头类型     VALUE,//值类型     SUB,//子表类型 }; struct Gener

c++数据结构之广义表

最近学习了广义表,我们知道广义表也是一种线性表,而顾名思义广义表就是不止一个表,下面来举个栗子: A=( ) B=(1 , 2,3) C=(1 ,2 ,3, ( a , b ,c) ) D=(1, 2, 3, (a,( b,c),d),4) 以上A,B,C,D都是广义表,只不过深度不一样,也就是括号的对数不一样,A是个特殊的广义表,即空表.B里面有三个元素,C里面有6个元素,包括一个子表(a,b,c),C也同理,只不过多了一层子表.由此可总结为一句话:表里有表 这样看可能不太直观,下面以广义表C

数据结构实践——广义表的原子统计

本文针对数据结构基础系列网络课程(5):数组与广义表的实践项目. [项目 -广义表的原子统计] 设计算法,求出给定广义表g中的原子个数和最大原子 [参考解答] (头文件glist.h是广义表算法库建设的成果,见链接-) #include <stdio.h> #include "glist.h" int atomnum(GLNode *g) //求广义表g中的原子个数 { if (g!=NULL) { if (g->tag==0) return 1+atomnum(g-

数据结构:广义表转置

问题描述 设计算法,将指定的广义表的内容原地逆置.例如:若广义表GL为[1, [2, 3], 4, [5, [6, 7], 8], 9],逆置后GL为 [9, [8, [7, 6], 5], 4, [3, 2], 1] . 基本思路 如题,一眼就能看出问题具有递归性,因此采用递归来求解,代码就非常简单了. Python实现 #encoding = utf8 def reverse_table(table): ''' 递归 ''' if not isinstance(table,list) or

【数据结构】邻接表的广度与深度遍历

邻接表:数组和链表相结合的方法.图中顶点一般用一个一维数组存储,也可以用单链表存储,每个顶点的邻接点构成一个线性表,一般为单链表. 无向图: 有向图: 代码: #include "stdio.h" #include "stdlib.h" #include "io.h" #include "math.h" #include "time.h" #define OK 1 #define ERROR 0 #defi

数据结构22:数组和广义表

本章主要介绍了数组和广义表的相关知识.数组章节,重点理解矩阵压缩存储的方式,在此基础上,学习矩阵的转置.乘法.和加法运算的实现:学习广义表时重点理解用递归的思想求广义表的深度和复制广义表. 本章内容: 1. 数据结构之多维数组 2. 矩阵压缩存储(十字链表.三元组顺序表.行逻辑 3. 矩阵转置算法及代码实现(三元组顺序表) 4. 矩阵乘法(行逻辑链接的顺序表)及代码实现 5. 矩阵加法(基于十字链表)及C语言代码实现 6. 广义表及M元多项式的C语言代码实现 7. 广义表的长度和深度 8. 广义