广义表
广义表是一种非线性的数据结构,是一种较为简单的数据结构,是线性表的扩展,是一个由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;
}
}
转载于:https://blog.51cto.com/10740590/1765497