您的位置:首页 > 理论基础 > 数据结构算法

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

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: