广义表
广义表是一种非线性的数据结构,是一种较为简单的数据结构,是线性表的扩展,是一个由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; } }
本文出自 “无心的执着” 博客,谢绝转载!
原文地址:http://10740590.blog.51cto.com/10730590/1765497