广义表(非线性结构)

广义表

广义表是一种非线性的数据结构,是一种较为简单的数据结构,是线性表的扩展,是一个由n个元素组成的序列。实现广义表主要是利用递归,将其分为子问题来进行解决。下面是一些常见类型的广义表:

1)A = ();          常称为“空表”

2)B = (a,b);          一般的广义表

3)C = (a, b, (c, d))         具有子表的广义表

4)D = (a, b, (c,(d)))        子表中有表的广义表

5)E = ((),())         空表嵌套空表

一般对于广义表采取的存储方式为链式存储,下面为简单的存储图示:

对于上面的一些常见类型的广义表,应当如何对其进行创建和操作?常见对于广义表会对其进行创建、求广义表的大小(这里指有值的节点)、求广义表的深度等操作。

下面是对广义表操作的具体程序代码:

--GeneralList.h文件
#pragma once
#include <stdlib.h>
//递归实现广义表

enum Type
{
     HEAD,     //头节点
     VALUE,     //直节点
     SUB,       //有子表的点
};

struct GeneralListNode
{
     Type _type;
     GeneralListNode* _next;      //指向同层下一个子节点
     union
     {
          int _value;
          GeneralListNode* _subLink;     //指向子表的指针
     };
     GeneralListNode(Type type = HEAD, int value = 0);       //构造节点
};

class  GeneralList
{
public:
     GeneralList();     //无参构造
     GeneralList(const char* str);    //有参构造
     GeneralList(const GeneralList& List);     //拷贝构造
     GeneralList& operator=(const GeneralList& List);   //赋值运算符重载
     ~GeneralList();     //析构函数
     
public:
     bool _isValue(char ch);      //判断是否为有效值
     GeneralListNode* _CreateList(const char*& str);     //创建广义表
     void print();        //打印
     size_t size();        //求广义表中有值节点个数
     size_t Depth();        //求广义表的深度
     GeneralListNode* _copy(GeneralListNode* head);    //广义表的拷贝
     
protected:
     void _print(GeneralListNode* head);        //打印
     size_t _size(GeneralListNode* head);       //大小
     size_t _depth(GeneralListNode* head);        //深度
     void Distroy(GeneralListNode* head);         //删除节点
     
protected:
     GeneralListNode* _head;
};

--GeneralList.cpp文件

#include "GeneralList.h"
#include <stdlib.h>
#include <assert.h>
#include <iostream>
using namespace std;

GeneralListNode::GeneralListNode(Type type, int value)       //构造节点
        :_type(type)
        , _next(NULL)
{
     if (_type == VALUE)      //若为值节点
     {
          _value = value;
     }
     if (_type == SUB)
     {
          _subLink = NULL;
     }
}

GeneralList::GeneralList()
      :_head(NULL)
{ }

GeneralList::GeneralList(const char* str)
{
     _head = _CreateList(str);
}

GeneralList::GeneralList(const GeneralList& List)
{
     _head = _copy(List._head);
}

GeneralList& GeneralList::operator=(const GeneralList& List)
{
     if (this != &List)
     {
          GeneralListNode* cur = _copy(List._head);
          Distroy(_head);
          _head = cur;
     }
     return *this;
}

GeneralList::~GeneralList()
{
     Distroy(_head);
}

bool GeneralList::_isValue(char ch)       //判断值是否有效
{
     if ((ch >= ‘0‘ && ch <= ‘9‘) ||
      (ch >= ‘a‘ && ch <= ‘z‘) ||
      (ch >= ‘A‘ && ch <= ‘Z‘))
     {
          return true;
     }
     else
     {
          return false;
     }
}

GeneralListNode* GeneralList::_CreateList(const char*& str)      //创造广义表
{
     assert(‘(‘==*str);
     ++str;          //将括号进行越过
     GeneralListNode* head = new GeneralListNode(HEAD, 0);
     GeneralListNode* cur = head;
     while (*str)
     {
          if (_isValue(*str))
          {
               cur->_next = new GeneralListNode(VALUE, *str);
               cur = cur->_next;
               str++;
          }
          else
          {
               if (*str == ‘(‘)         //表示子表开始
               {
                    GeneralListNode* tail = new GeneralListNode(SUB, 0);
                    cur->_next = tail;
                    cur = cur->_next;
                    tail->_subLink = _CreateList(str);
               }
               else if (*str == ‘)‘)        //表示子表结束
               {
                    str++;
                    return head;
               }
               else
               {
                    str++;
               }
          }
     }
     assert(false);
     return head;
}

void GeneralList::print()      //打印广义表
{
     _print(_head);
     cout << endl;
}

size_t GeneralList::size()        //广义表大小
{
     return _size(_head);
}

size_t GeneralList::Depth()    //广义表深度
{
     return _depth(_head);
}

GeneralListNode* GeneralList::_copy(GeneralListNode* head)   //广义表的拷贝
{
     GeneralListNode* cur = head;
     GeneralListNode* newhead = new GeneralListNode(HEAD, 0);
     GeneralListNode* ptr = newhead;    //新建表的指针
     while (cur)
     {
          if (cur->_type == VALUE)
          {
               ptr->_next = new GeneralListNode(VALUE, cur->_value);
               ptr = ptr->_next;
          }
          else if (cur->_type == SUB)
          {
               ptr->_next = new GeneralListNode(SUB, 0);
               ptr = ptr->_next;
               ptr->_subLink = _copy(cur->_subLink);
          }
          cur = cur->_next;
     }
     return newhead;
}

void GeneralList::_print(GeneralListNode* head)     //打印
{
     GeneralListNode* cur = head;
     while (cur)
     {
          if (cur->_type == HEAD)
          {
               cout << "(" ;
          }
          else if (cur->_type == VALUE)
          {
               cout << (char)cur->_value;
               if (cur->_next)
               {
                    cout << ",";
               }
          }
          else if (cur->_type == SUB)
          {
               _print(cur->_subLink);         //打印子表
               if (cur->_next)
               {
                    cout << ",";
               }
          }
          cur = cur->_next;
     }
     cout << ")";
}

size_t GeneralList::_size(GeneralListNode* head)      //大小(只计算值节点)
{
     size_t size = 0;
     GeneralListNode* cur = head;
     while (cur)
     {
          if (cur->_type == VALUE)
          {
               size++;
          }
          else if (cur->_type == SUB)
          {
               size += _size(cur->_subLink);
          }
          cur = cur->_next;
     }
     return size;
}

size_t GeneralList::_depth(GeneralListNode* head)       //深度
{
     size_t deep = 1;
     GeneralListNode* cur = head;
     while (cur)
     {
          if (cur->_type == SUB)          //若遇到有子表的节点,计算子表的深度,同时进行记录,找出最大的深度
          {
               size_t pdepth = _depth(cur->_subLink);
               if (pdepth + 1 > deep)
               {
                    deep = pdepth + 1;
               }
          }
          cur = cur->_next;
     }
     return deep;
}

void GeneralList::Distroy(GeneralListNode* head)    //删除所有节点
{
     GeneralListNode* cur = head;
     while (cur)
     {
          GeneralListNode* tmp = cur;
          if (cur->_type == SUB)           //若节点为有子表的节点,则先递归删除子表节点
          {
               Distroy(cur->_subLink);
          }
          cur = cur->_next;
          delete tmp;
     }
}
时间: 2024-07-28 17:26:53

广义表(非线性结构)的相关文章

【代码】C++实现广义表及其测试用例

广义表是我第一次用递归接触链式的数据结构,其结构如下: HEAD->VAL->VAL->LINK(->HEAD.....)->VAL->......     在这里,我们的头结点与link节点是不存储数据的,由此我们便可以定义出节点的数据结构: typedef int DataType; enum NodeType//枚举类型定义节点类型 { HEAD, VALUE, SUB, }; struct GeneralizedNode { public: Generalize

广义表总结

/**********************          WZ  ASUST 2016 表的实现与表头表尾问题 缺函数:找值 **********************/ #include<iostream> #include<assert.h> #include<string> using namespace std;   //实现广义表的结构 // 节点的类型:来代替直接写3类 结构体 enum Type//枚举类型 {     HEAD,     VAL

数据结构广义表实验

一.问题描述: 1.题目内容:识别广义表的“头”或“尾”的演示 写一个程序,建立广义表的存储结构,演示在此存储结构上实现的广义表求头/求尾操作序列的结果. 2.基本要求 (1)设一个广义表允许分多行输入,其中可以任意地输入空格符,原子是不限长的仅字母或数字组成的串. (2)广义表采用如教材中结点的存储结构,试按表头和表尾的分解方法编写建立广义表存储结构的算法. (3)对已建立存储结构的广义表施行操作,操作序列为一个仅由“t“或”h”组成的串,它可以是空串(此时印出整个广义表),自左至右施行各操作

[转]广义表

(C版) #include <stdio.h>#include <malloc.h>#define OK 1#define ERROR -1#define status inttypedef struct gnode{ int tag; union {  char atom;  struct gnode *sublist; } val; struct gnode *link;} *Gnode;Gnode creatglist(char *s){//创建广义表 Gnode h; ch

广义表的基本操作实现

广义表的四个特征:(1)广义线性表:(2)元素复合性:(3)元素递归性:(4)元素共享性 广义表的上述四个特征对于他的使用价值和应用效果起到了很大的作用.广义表的结构相当灵活,它可以兼容线性表.数组.树和有向图等各种常用的数据结构.当二维数组的每行或每列作为子表处理时,二维数组就是一个广义表:如果限制广义表中元素的共享和递归,广义表和树对应:如果限制广义表的递归并允许数据共享,则广义表和图对应. 广义表的基本操作有:(1)创建一个广义表(我以头尾链表作为存储结构):(2)取表头:(3)取表尾:(

递归实现广义表

广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列.由于在表的描述中可以嵌套表,允许表中有表,所以可以通过递归实现广义表. 具体实现如下: 头文件 #pragma once //实现广义表的结构 enum Type//枚举类型 { HEAD, VALUE, SUB, }; struct GeneralizedNode//广义表的结点 { Type _type;//类型 GeneralizedNode* _next;//值相同层的下一个节点 union//共用体/联合 { int 

广义表 (五)

5.1广义表-广义表的定义和基本运算 顾名思义,广义表是线性表的推广.也有人称其为列表(Lists,用复数形式以示与统称的表List 的区别). ⒈广义表的定义和性质 我们知道,线性表是由n 个数据元素组成的有限序列.其中每个组成元素被限定为单元素,有时这种限制需要拓宽.例如,中国举办的某体育项目国际邀请赛,参赛队清单可采用如下的表示形式: (俄罗斯,巴西,(国家,河北,四川),古巴,美国,(),日本) 在这个拓宽了的线性表中,韩国队应排在美国队的后面,但由于某种原因未参加,成为空表.国家队.河

广义表存储

节点形态: 存储结构: 每个节点都包含一个标志域,如果为0(即原子),那么仅含一个值域,如果是1(列表),那么说明该节点包含两个指针域. 需要注意的是求广义表长度的操作,其实计算的是根节点及其兄弟的个数,比如图2中广义表的长度为2,图3中广义表的长度为4. 深度的定义方式是递归式的,定义空表深度为1,原子深度为0,广义表的深度比其子表的深度的最大值大1.故图2的深度为3,图3的深度为2. 注意:任何一个非空列表其表头可能是原子,也可能是列表,但是其表尾必定是列表,也就是说不存在这样的广义表: 具

5-1-数组的顺序存储结构-数组和广义表-第5章-《数据结构》课本源码-严蔚敏吴伟民版

课本源码部分 第5章  数组和广义表 - 数组的顺序存储结构 ——<数据结构>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑        本源码引入的文件  链接? Status.h        相关测试数据下载  链接? 无数据