广义表

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


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

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

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

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

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



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


wKioL1cWFSOi9a1lAAAd6Nai4PM442.png


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


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

--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;
     }
}