广义表的创建及基本操作

存储结构(头尾链)

结构图

在这里插入图片描述
在这里插入图片描述

代码

typedef enum{ATOM,LIST}ElemTag;//ATOM==0:原子;LIST==1:子表;
typedef struct GLNode {
	ElemTag tag;//公共部分,区分原子结点和表结点
	union {//原子结点和表结点的联合部分
		char atom;//原子结点的值域
		struct { struct GLNode* hp, * tp; }ptr;//结点指针域,hp为当前子表头指针
		                                      //tp指向当前子表的下一并列子表
	};
}*GList;

基本操作

建立广义表

基本项

  • 当T为空表,置空广义表
  • 当T为单字符串,建立原子结点的子表

归纳项

  • sub为脱去最外层括号的子串,其中sub=S1...Sn为非空字符串。对每一个Si建立一个表结点,并令hp为建立子表的头指针,tp指针指向在他之后建立的表结点
Status CreatGList(GList& L, HString T) {//创建广义表
	HString emp, sub, str;
	GList p, q;
	PushHString(emp, "()");
	//当T为空表串,置空广义表
	if (!CompareHString(T, emp)) L = NULL;//创建空表
	else {
		if (!(L = (GList)malloc(sizeof(GLNode)))) return ERROR;
	//当T为单字符串,建立原子结点子表
		if (T.length == 1) {
			L->tag = ATOM;
			L->atom = T.ch[0];
		}
	//归纳项
		else {
			L->tag = LIST;p = L;
			SubHString(sub, T, 2, T.length - 2);//脱去外层括号
			do {
				sever(str, sub);//第一次编写为sever(str,T)...一直报错,找了三四个钟头!!!
				CreatGList(p->ptr.hp, str);q = p;//hp为建立子表的头指针
				if (!EmptHString(sub)) {
					p = (GList)malloc(sizeof(GLNode));//tp指向在它之后建立的结点
					p->tag = LIST;q->ptr.tp = p;
				}
			} while (!EmptHString(sub));
			q->ptr.tp = NULL;
		}
	}
	return OK;
}

字串分割函数

  • 判断分割位置
  • 当字串有,
  • 当字串没有,
Status sever(HString& S, HString& T) {//将串T分割为‘,’前和‘,’后两部分
	int n = T.length;int i = 0;int k = 0;//k为尚未配对的左括号数
										 //之所以要记录左括号数是因为有子串为原子表,没有‘,’出现
	HString ch;
	//判断分割位置
	do {
		i++;
		SubHString(ch, T, i, 1);
		if (ch.ch[0] == '(') ++k;
		else if (ch.ch[0] == ')') --k;
	} while (i < n && (ch.ch[0] != ',' || k != 0));//当k为零,即说明已经搜索了一队括号的内容
												   //也即说明当前串为原子表,没有‘,’
	//当字串有“,”
	if (i < n) {
		SubHString(S, T, 1, i - 1);
		SubHString(T, T, i + 1, n - i);
	}
	//当字串没有“,”
	else {
		CopyHString(S, T);
		ClearHString(T);
	}
	return OK;
}

求广义表深度

基本项

  • 空表深度为1
  • 原子表深度为0

归纳项

  • 列表深度为各子表最大深度加1
Status DepthGList(GList L) {//求列表深度
	if (!L) return 1;//空表深度为1
    if (L->tag == 0) return 0;//原子表深度为0
	int dep, max ;GList pp;
	for (max = 0, pp=L;pp;pp = pp->ptr.tp) {//遍历列表,归纳项为列表深度为各个子表深度最大值加1
		dep = DepthGList(pp->ptr.hp);
		if (dep > max) max = dep;
	}
	return max + 1;
}

打印广义表

void PrintGList2(GList L) {
	GLNode* p;
	if (!L)
	{
		cout << "()";
	}
	else
	{

		if (L->tag == ATOM)
		{
			cout << L->atom;
		}
		else
		{
			p = NULL;
			cout << '(';
			p = L;
			while (p)
			{
				PrintGList2(p->ptr.hp);
				p = p->ptr.tp;
				if (p)
				{
					cout << ',';
				}
			}
			cout << ')';
		}
	}
}
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值