C++如何实现广义表详解

2020-01-06 15:49:23王冬梅

以下给出几种简单的广义表模型:

广义表c语言,广义表的运算c语言,广义表head,tail,运算

 

由上图我们可以看到,广义表的节点类型无非headvaluesub三种,这里设置枚举类型,利用枚举变量来记录每个节点的类型:


enum Type
{
  HEAD,  //头节点
  VALUE, //值节点
  SUB,  //子表节点
};

每个节点都有自己的类型以及next指针,除此之外,如果该节点是VALUE类型还要分配空间存储该节点的有效值;但是若该节点是SUB类型,就需定义一个指针指向子表的头。

这里我们可以用联合来解决这个问题。

(联合(或共同体)是一种不同数据类型成员之间共享存储空间的方法,并且联合体对象在同一时间只能存储一个成员值)

构造节点:


struct GeneralizedNode
{
  Type _type;    // 1.类型
  GeneralizedNode* _next; //2.指向同层的下一个节点
  union
  {
    char _value;  // 3.有效值
    GeneralizedNode* _subLink;   // 3.指向子表的指针
  };
   
  GeneralizedNode(Type type = HEAD, char value = '0')
  :_value(value)
  ,_type(type)
  , _next(NULL)
  {
    if (_type == SUB)
    {
      _subLink = NULL;
    }
  }
};

广义表的定义及基本操作: 


class Generalized
{
public:
  //无参的构造函数,建立空的广义表
  Generalized();
  //建造广义表,有参数的构造函数
  Generalized(const char* str);
  //打印广义表
  void Print();
  //获取值节点的个数
  size_t Amount();
  //获取广义表的深度
  size_t Depth();
  //拷贝构造
  Generalized(const Generalized& g);
  ////赋值运算符的重载
  Generalized& operator=(const Generalized& g);
  ////析构函数
  ~Generalized();
 
protected:
  void _Print(GeneralizedNode* head);
  GeneralizedNode* _CreatList(const char*& str);
  size_t _Amount(GeneralizedNode* head);
  GeneralizedNode* _Copy(GeneralizedNode* head);
  void _Destory(GeneralizedNode* head);
protected:
  GeneralizedNode* _head;  //记录广义表头指针
};

初始化建立广义表进行循环递归。遍历字符串时遇到字符就建立值节点,遇到'('就进行递归并建立子表;遇到')'就结束当前子表的建立,并返回当前子表的头指针。 


GeneralizedNode* _CreatList(const char*& str)
{
  assert(*str == '(');
  GeneralizedNode* head = new GeneralizedNode(HEAD,'0');
  GeneralizedNode* cur = head;
  str++;
  while (str != '')
  {
    if ((*str >= '0'&&*str <= '9') || (*str >= 'a'&&*str <= 'z') || (*str >= 'A'&&*str <= 'Z'))
    {
      cur->_next = new GeneralizedNode(VALUE, *str);
      cur = cur->_next;
    }
    else if (*str == '(')
    {
      cur->_next = new GeneralizedNode(SUB);
      cur = cur->_next;
      cur->_subLink = _CreatList(str);
    }
    else if (*str == ')')
    {
      return head;
    }
    str++;
  }
  return head;
}