构建一张广义表,计算广义表的长度和深度。
/*
*广义表的实现*
1.构建广义表
形如(a,d,(e,(w,c),(),(r,t)),(((q))));其中空表表示为(),括弧中不添加任何字符
2.求广义表长度
3.广义表深度
*/
#include<iostream>
#include<string>
#include<fstream>
using namespace std;
//构建广义表数据节点
class GLNode
{
public:
int tag;//设置标志位,判断是否存在子表
//定义共用体,当前是否存储数据与是否需生成子表不并存
union
{
char data;//存储数据
class GLNode *sub_list;//子表指针
}val;
class GLNode *link;//后继节点指针
};
//广义表的实现
class GList
{
public:
GList(){}
~GList()
{
release(G);
}
//构建广义表,形参name为文件名
void Create(string name)
{
read.open(name);
getline(read, str);//读取一行字符
read.close();
cout << str << endl;
G = CreateGL(G, str);//构建广义表
}
//求广义表长度
int length()
{
int n = get_length(G->val.sub_list);
return n;
}
//求广义表深度
int deep()
{
int n = get_deep(G);
return n;
}
//释放节点空间
void release(GLNode *g)
{
if (g == NULL)//表空,释放当前
{
free(g);
}
else
{
if (g->tag==1)//存在子表,释放子表
{
release(g->val.sub_list);
}
else//释放后继节点
{
release(g->link);
}
}
}
private:
ifstream read;
GLNode *G;
string str;
//构建广义表,g接收广义表节点,s存储当前字符串
GLNode *CreateGL(GLNode *g, string &s)
{
char ch;
g = (GLNode *)malloc(sizeof(GLNode));
if (str.length() != 0)//当前str长度不为0时,生成广义表
{
ch = str[0];//读取串中第一个字符
if (ch == '(')//当ch为‘(’时,构建子表
{
str.assign(str.substr(1, str.length() - 1));//求当前串的子串
g->tag = 1;//设置标志位
g->val.sub_list = CreateGL(g, str);//构建子表
}
else if (ch == ')')//ch若为')'时,表构建完成
{
g = NULL;
}
else//若为表值则存储
{
g->tag = 0;
g->val.data = ch;
}
}
else//若当前串长度为0则完成广义表的构建
{
g = NULL;
}
ch = str[1];//读取当前串第二个字符
if (g != NULL)
{
if (ch == ',')//ch若为','则创建同层后继节点
{
str.assign(str.substr(2, str.length() - 2));
g->link = CreateGL(g, str);
}
else if (ch == ')')//ch若为')'则同层子表构建完成
{
str.assign(str.substr(1, str.length() - 1));
g->link = NULL;
return g;
}
}
return g;
}
//求广义表长度,形参g接收广义表首节点中子表地址
int get_length(GLNode *g)
{
int n = 0;
if (g->link == NULL)//若第二层后一节点为空,则返回长度为1
{
n = 1;
return n;
}
else//若不为空,递归调用直至为空
{
n = get_length(g->link);
}
return (n + 1);
}
//求广义表深度,形参g接收广义表首节点
int get_deep(GLNode *g)
{
int max = 0, dep;
if (g == NULL)//若当前节点为空,则深度为0
{
return 0;
}
if (g->val.sub_list == NULL)//若当前节点中子表地址为空,则深度为1
{
return 1;
}
GLNode *g1 = g->val.sub_list;//以上条件不满足,则g1指向当前节点的子表地址
while (g1 != NULL)
{
if (g1->tag == 1)//若判断标志为1,则仍存在子表
{
dep = get_deep(g1);//递归调用至下一层求深度
max = max < dep ? dep : max;//递归返回时取当前深度值max和下一层深度值dep中的最大值
}
g1 = g1->link;//其他情况,g1指向同层中后一节点直至g1为空
}
return max + 1;
}
};
int main()
{
GList list;
list.Create("data");//构建广义表,测试数据文件名为"data"
cout << "Length: " << list.length() << endl;//求长度
cout << "Deep: " << list.deep() << endl;//求深度
return 0;
}
一次测试结果: