数据结构::关于广义表的那些事~~

来源:互联网 发布: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
原创粉丝点击