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;
}