数据结构::关于广义表的那些事~~
来源:互联网 发布:rfid防碰撞算法 编辑:程序博客网 时间:2024/05/22 12:11
1、广义表
1.1广义表的定义
1.2广义表的表示
1.3广义表的性质
1.4广义表的实现
【广义表的定义】:是由N个元素组成的有限序列,它的定义是递归的,因为它允许表中有表。
【广义表的表示】:
广义表是n(n≥0)个元素a1,a2,…,ai,…,an的有限序列。
其中:
①ai--或者是原子或者是一个广义表。
②广义表通常记作:
Ls=( a1,a2,…,ai,…,an)。
③Ls是广义表的名字,n为它的长度。
④若ai是广义表,则称它为Ls的子表。
注意:
①广义表通常用圆括号括起来,用逗号分隔其中的元素。
②为了区分原子和广义表,书写时用大写字母表示广义表,用小写字母表示原子。
③若广义表Ls非空(n≥1),则al是LS的表头,其余元素组成的表(a1,a2,…,an)称为Ls的表尾。
④广义表是递归定义的
举例如下:
【广义表的性质】:它是非线性结构的,是线性表的一种扩展。
【广义表的实现】:
我们以下图为例进行说明和实现:
我们进行分析:
1)在我们实现的广义表中定义的时候都带了头结点
2)我们不难发现,每一个节点都会有自己的类型和指向下一个节点的指针,类型无非就是这三种:带头结点,数值,和有子表的,因此我们可以这样定义
enum Type{HEAD,VALUE,SUB};struct GeneralListNode{GeneralListNode(const Type& type,char value = 0):_type(type),_next(NULL),_sublink(NULL){_value = value; //注意这块直接赋值}Type _type;GeneralListNode* _next;union{char _value;GeneralListNode* _sublink;};};3)那么接下来我们就来实现广义表的其它接口
class GeneralList{public:typedef GeneralListNode Node;public://构造函数GeneralList():_head(NULL){}GeneralList(const char* str):_head(NULL){_head = Creat(str);}Node* Creat(const char*&str) //注意传引用{assert(str&&*str == '(');Node* head = new Node(HEAD);//先定义一个只有头节点的Node* cur = head;str++;//接下来分情况:有值得或者是有子表的,或者其他while(*str){if((*str >= '0' && *str<='9')||(*str>='a' && *str<='z')||(*str>='A' && *str<='Z')){Node* ret = new Node(VALUE,*str);cur->_next = ret;cur = cur->_next;str++;}else if(*str == '('){Node* ret = new Node(SUB);cur->_next = ret;//str++;ret->_sublink = Creat(str);cur = cur->_next;}else if(*str == ')') //已经到广义表的最后了{str++;return head;}else{++str;}}return head;}//拷贝构造函数GeneralList(const GeneralList& g){_head = Copy(g._head);}Node* Copy(Node* head){assert(head&&head->_type==HEAD);Node* cur = head; //原来的Node* tail = new Node(HEAD); //指向子表Node* newhead = tail;while(cur){if(cur->_type == VALUE){Node* ret = new Node(cur->_type,cur->_value);tail->_next = ret;tail = tail->_next;cur = cur->_next;}else if(cur->_type == SUB){Node* ret = new Node(cur->_type);tail->_next = ret;tail = tail->_next;tail->_sublink = Copy(cur->_sublink);cur = cur->_next;}elsecur = cur->_next;}return newhead;}//赋值运算符重载GeneralList& operator=(const GeneralList& g){//普通的传统写法if(this != &g){Node* temp = Copy(g._head);if(_head!=NULL)Destory(_head);_head = temp;}return *this;//现在的简洁写法:/*:写法一:Node* Assign temp(g);std::swap(_head,temp._head);return *this;写法二:Node* Assign(GeneralList g){swap(_head,g._head);return *this;}写法三:Node* Assign(const GeneralList& g){Assign temp(g._head);swap(_head,temp._head);return *this;}*/}//析构函数~GeneralList(){if(_head){Destory(_head);}_head = NULL;}void Destory(Node* head){assert(head&&head->_type==HEAD);Node* cur = head;while(cur){if(cur->_type == SUB){Destory(cur->_sublink);}Node* del = cur;cur = cur->_next;delete del;}}//求广义表的元素的个数size_t Size(){return _Size(_head);}size_t _Size(Node* head){assert(head&&head->_type==HEAD);size_t count = 0;Node* cur = head;while(cur){if(cur->_type == VALUE){count++;}if(cur->_type == SUB){count += _Size(cur->_sublink);}cur = cur->_next;}return count;}//求广义表的深度size_t Depth(){return _Depth(_head);}size_t _Depth(Node* head){assert(head&&head->_type==HEAD);size_t maxSize = 1;size_t depth = 1;Node* cur = head;while(cur){if(cur->_type == SUB){if(depth+1 > maxSize){maxSize = depth+1;}depth = _Depth(cur->_sublink);}cur = cur->_next;}return maxSize;}//打印函数void Print(){_Print(_head);cout<<endl;}//(a,b,(c,d))void _Print(Node* head){assert(head&&head->_type==HEAD);Node* cur = head;cout<<'(';while(cur){if(cur->_type == HEAD){cur = cur->_next;}else if(cur->_type == VALUE){cout<<cur->_value;if(cur->_next){cout<<',';cur = cur->_next;}else{return ;}}else if(cur->_type == SUB){_Print(cur->_sublink);cout<<')';if(cur->_next){cout<<',';cur = cur->_next;}else{break;}}}cout<<')';}protected:Node* _head;};4)注意:我们在实现广义表的时候有的广义表是有子表的嵌套的,因此实现的时候,我们会采取递归的方式,一般在类里实现成员函数的递归的时候我们不直接进行递归的实现,而是将它封装成一个函数。但是读者看我上面实现的函数,举个例子:看构造函数,我没有直接在定义构造函数的函数体里实现,而是封装了一个Creat函数。
最后我把完整的代码附上:
#include<iostream>#include<assert.h>using namespace std;//广义表的类型:三种:enum Type{HEAD,VALUE,SUB};struct GeneralListNode{GeneralListNode(const Type& type,char value = 0):_type(type),_next(NULL),_sublink(NULL){_value = value; //注意这块直接赋值}Type _type;GeneralListNode* _next;union{char _value;GeneralListNode* _sublink;};};class GeneralList{public:typedef GeneralListNode Node;public://构造函数GeneralList():_head(NULL){}GeneralList(const char* str):_head(NULL){_head = Creat(str);}Node* Creat(const char*&str) //注意传引用{assert(str&&*str == '(');Node* head = new Node(HEAD);//先定义一个只有头节点的Node* cur = head;str++;//接下来分情况:有值得或者是有子表的,或者其他while(*str){if((*str >= '0' && *str<='9')||(*str>='a' && *str<='z')||(*str>='A' && *str<='Z')){Node* ret = new Node(VALUE,*str);cur->_next = ret;cur = cur->_next;str++;}else if(*str == '('){Node* ret = new Node(SUB);cur->_next = ret;//str++;ret->_sublink = Creat(str);cur = cur->_next;}else if(*str == ')') //已经到广义表的最后了{str++;return head;}else{++str;}}return head;}//拷贝构造函数GeneralList(const GeneralList& g){_head = Copy(g._head);}Node* Copy(Node* head){assert(head&&head->_type==HEAD);Node* cur = head; //原来的Node* tail = new Node(HEAD); //指向子表Node* newhead = tail;while(cur){if(cur->_type == VALUE){Node* ret = new Node(cur->_type,cur->_value);tail->_next = ret;tail = tail->_next;cur = cur->_next;}else if(cur->_type == SUB){Node* ret = new Node(cur->_type);tail->_next = ret;tail = tail->_next;tail->_sublink = Copy(cur->_sublink);cur = cur->_next;}elsecur = cur->_next;}return newhead;}//赋值运算符重载GeneralList& operator=(const GeneralList& g){//普通的传统写法if(this != &g){Node* temp = Copy(g._head);if(_head!=NULL)Destory(_head);_head = temp;}return *this;//现在的简洁写法:/*:写法一:Node* Assign temp(g);std::swap(_head,temp._head);return *this;写法二:Node* Assign(GeneralList g){swap(_head,g._head);return *this;}写法三:Node* Assign(const GeneralList& g){Assign temp(g._head);swap(_head,temp._head);return *this;}*/}//析构函数~GeneralList(){if(_head){Destory(_head);}_head = NULL;}void Destory(Node* head){assert(head&&head->_type==HEAD);Node* cur = head;while(cur){if(cur->_type == SUB){Destory(cur->_sublink);}Node* del = cur;cur = cur->_next;delete del;}}//求广义表的元素的个数size_t Size(){return _Size(_head);}size_t _Size(Node* head){assert(head&&head->_type==HEAD);size_t count = 0;Node* cur = head;while(cur){if(cur->_type == VALUE){count++;}if(cur->_type == SUB){count += _Size(cur->_sublink);}cur = cur->_next;}return count;}//求广义表的深度size_t Depth(){return _Depth(_head);}size_t _Depth(Node* head){assert(head&&head->_type==HEAD);size_t maxSize = 1;size_t depth = 1;Node* cur = head;while(cur){if(cur->_type == SUB){if(depth+1 > maxSize){maxSize = depth+1;}depth = _Depth(cur->_sublink);}cur = cur->_next;}return maxSize;}//打印函数void Print(){_Print(_head);cout<<endl;}//(a,b,(c,d))void _Print(Node* head){assert(head&&head->_type==HEAD);Node* cur = head;cout<<'(';while(cur){if(cur->_type == HEAD){cur = cur->_next;}else if(cur->_type == VALUE){cout<<cur->_value;if(cur->_next){cout<<',';cur = cur->_next;}else{return ;}}else if(cur->_type == SUB){_Print(cur->_sublink);cout<<')';if(cur->_next){cout<<',';cur = cur->_next;}else{break;}}}cout<<')';}protected:Node* _head;};/**********测试函数****************/void Test(){GeneralList g1("(a,b,(c,d))");cout<<g1.Size()<<endl;cout<<g1.Depth()<<endl;g1.Print();GeneralList g2(g1);g2.Print();GeneralList g3;g3 = g2;g3.Print();}int main(){Test();return 0;}
0 0
- 数据结构::关于广义表的那些事~~
- 【数据结构】广义表的实现
- C++ 数据结构 *** 广义表的部分实现
- 数据结构---->广义表
- 数据结构 广义表
- 数据结构广义表实验
- 数据结构--广义表
- 数据结构--广义表
- [数据结构复习]广义表
- 数据结构 - 广义表
- 数据结构-广义表
- 数据结构-- 广义表
- 数据结构8.广义表
- 数据结构:有关广义表
- 数据结构:广义表
- 数据结构之广义表
- C++ 数据结构 广义表
- 数据结构-广义表
- 使用chcp命令查看系统编码
- break与continue的用法及区别
- 关于import moudle 出现的错误 Error(2.0)
- 解决log4j找不到指定的路径的解决方法
- CollapsingToolbarLayout属性介绍
- 数据结构::关于广义表的那些事~~
- 荒岛求生第九关
- Redis未授权访问缺陷让服务器沦为肉鸡
- oracle中substr和instr
- github 删除github上的项目
- LeetCode 1 two sum
- Matlab教程 学习之基础知识
- Json 转换
- 【android学习】检测android主屏,并把app从后台切换置前台