数据结构::关于广义表的那些事~~
2016-12-13 12:15
417 查看
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; } else cur = 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; } else cur = 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;
}
相关文章推荐
- 关于数据结构中的“回文问题”
- 关于数据结构的一些术语的中英文对照表
- 关于BIOS的那些事----不要老整三岁的脑筋急转弯,咱们来整点五岁的(上)
- 关于数据结构
- Java中关于可变长参数的那些事
- 关于数据结构
- 数据结构中的关于拉链的举例
- 跪求一道关于c语言和数据结构的问题
- 关于BIOS的那些事----不要老整三岁的脑筋急转弯,咱们来整点五岁的(下)
- 关于树的数据结构初始化问题?
- 关于数据结构
- 《Delphi 算法与数据结构》学习与感悟[4]: 关于 const
- 对关于字符驱动的一些重要数据结构(file_operations, file, inode, cdev)的理解
- 关于java的数据结构和算法
- 关于数据结构的一些术语的中英文对照表
- 关于拓扑排序(参考严蔚敏数据结构)
- 关于数据结构导出的问题
- 数据结构,关于栈的实现
- 杂谈2008—关于游戏和游戏的那些事
- 关于WAS的那些事....