广义表求长度和深度C++

构建一张广义表,计算广义表的长度和深度。

/*
			*广义表的实现*

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

一次测试结果:



  • 5
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值