广义表_2(C风格实现)

就快考数据结构了 复习中,之前写过一篇广义表的 是用头尾结点表示法实现的,这次的是用兄弟孩子结点表示法实现的,相比之下,这种表示法的要简洁的。虽然考试这方面的应该不考多少,但是兴趣所在,以后学LISP的话 也有点基础。 之前写的广义表

//头文件

#include <iostream>
using namespace std;

//广义表存储结构
struct GL_Node
{
	int tag;
	union {
		char data; //原子值
		GL_Node *sublist; //指向子表的指针
	} val;
	GL_Node *link;
};

int GL_Length(GL_Node *G)
{
	//G为广义表表头节点指针
	int n=0;
	G=G->val.sublist;
	while(G)
	{
		n++;
		G=G->link;
	}
	return n;
}

int GL_Depth(GL_Node *G)
{
	int max=0,dep;
	if(G->tag == 0)
		return 0;
	G=G->val.sublist;
	if(!G)
		return 1;
	while(G)
	{
		if(G->tag == 1)
		{
			dep=GL_Depth(G);
			if(dep > max)
				max=dep;
		}
		G=G->link;
	}
	return (max+1);
}

GL_Node *GL_CreateGL(char *&s)
{
	GL_Node *h;
	char ch;
	ch=*s;   //取一个扫描字符
	s++;  //指向下一个待扫描字符
	if(ch != '\0')
	{
		h=new GL_Node;
		if(ch == '(')
		{
			h->tag=1;
			h->val.sublist=GL_CreateGL(s);  //递归构造子表
		}
		else if(ch == ')')
			h=NULL;  //右括号时,子表为空
		else
		{
			h->tag=0;
			h->val.data=ch; 
		}
	}
	else
		h=NULL;
	ch=*s;
	s++;
	if(h)
	{
		if(ch == ',')   //递归构造后序子表
			h->link=GL_CreateGL(s);
		else
			h->link=NULL;  
	}
	return h;
}

void GL_Display(GL_Node *G)
{
	if(G)
	{
		if(G->tag == 1)
		{
			cout<<"(";
			if(G->val.sublist)
				GL_Display(G->val.sublist); //递归输出子表
			else
				cout<<"";
		}
		else
			cout<<G->val.data;
		if(G->tag == 1)
			cout<<")";
		if(G->link)
		{
			cout<<",";
			GL_Display(G->link);
		}
	}
}

GL_Node *GL_Copy(GL_Node *G)
{
	//复制广义表
	GL_Node *Q;
	if(!G)
		return NULL;
	Q=new GL_Node;
	Q->tag=G->tag;
	if(G->tag == 1)
		Q->val.sublist=GL_Copy(G->val.sublist);
	else
		Q->val.data=G->val.data;
	Q->link=GL_Copy(G->link);
	return Q;
}

//取表头
GL_Node *Get_Head(GL_Node *G)
{
	GL_Node *p=G->val.sublist;
	GL_Node *q,*t;
	if(!p)
	{
		cout<<"空表无法求表头"<<endl;
		return NULL;
	}
	else if(G->tag == 0)
	{
		cout<<"原子结点无法求表头"<<endl;
		return NULL;
	}
	if(p->tag == 0)
	{
		q=new GL_Node;
		q->tag=0;
		q->val.data=p->val.data;
		q->link=NULL;
	}
	else
	{
		t=new GL_Node;
		t->tag=1;
		t->val.sublist=p->val.sublist;
		t->link=NULL;
		q=GL_Copy(t);
		delete t;
	}
	return q;
}

//取表尾
GL_Node *Get_Tail(GL_Node *G)
{
	GL_Node *p=G->val.sublist;
	GL_Node *q,*t;
	if(!G)
	{
		cout<<"空表不能求表尾"<<endl;
		return NULL;
	}
	else if(G->tag == 0)
	{
		cout<<"原子结点不能求表尾"<<endl;
		return NULL;
	}
	p=p->link;
	t=new GL_Node;
	t->tag=1;
	t->link=NULL;
	t->val.sublist=p;
	q=GL_Copy(t);
	delete t;
	return q;
}

void Replace(GL_Node *&G,char x,char y)
{
	GL_Node *p,*q;
	p=G->val.sublist;
	while(p)
	{
		if(p->tag == 0)
		{
			if(p->val.data == x)
				p->val.data=y;
		}
		else
			Replace(p,x,y);
		p=p->link;
	}
}

void GL_Insert(GL_Node *&G,char x,char y)
{
	//在广义表中元素x的后面插入y,有多个x时,插在每一个后面
	if(!G)
		return;
	GL_Node *p=G->val.sublist;
	GL_Node *q=NULL;
	while(p)
	{
		if(p->tag == 0)
		{
			if(p->val.data == x)
			{
				q=new GL_Node;
				q->tag=0;
				q->val.data=y;
				q->link=p->link;
				p->link=q;
				cout<<"插如成功"<<endl;
			}
		}
		else
			GL_Insert(p,x,y);
		p=p->link;
	}
}

void GL_Delete(GL_Node *&G,char x)
{
	//在广义表中删除x,有多个,就全部删除
	GL_Node *p,*q;
	if(!G)
		return;
	p=G->val.sublist;
	q=NULL;
	while(p)
	{
		if(p->tag == 0)
		{
			if(p->val.data == x)
			{
				if(!q) //说明该结点是该子表的第一个元素
				{
					G->val.sublist=p->link;
					delete p;
					//删完一个之后,要给p赋上合适的值,使得程序可以继续递归删除
					p=G->val.sublist; 
					continue;
				}
				else
				{
					q->link=p->link;
					delete p;
					//删完一个之后,要给p赋上合适的值,使得程序可以继续递归删除
					p=q->link;
					continue;
				}
				cout<<"删除成功"<<endl;
			}
			else
				q=p;
		}
		else
		{
			GL_Delete(p,x);
			q=p; //保证程序在递归返回之后,q的位置在p前面,保证删除操作正确,核心的一句。
		}
		p=p->link;
	}
}

主函数

#include "glist.h"

int main()
{
	char *s="(a,(b,c,d),(d,l),d,p))";
	GL_Node *G;
	G=GL_CreateGL(s);
	cout<<"表的深度为:"<<GL_Depth(G)<<endl;

	cout<<"表的长度为:"<<GL_Length(G)<<endl;

	cout<<"遍历表:";
	GL_Display(G);
	cout<<endl;

	GL_Node *H,*T;
	H=Get_Head(G);
	cout<<"表的表头为:";
	GL_Display(H);
	cout<<endl;

	cout<<"表尾为:";
	T=Get_Tail(G);
	GL_Display(T);
	cout<<endl;

	cout<<"将原表中的d全部替换成k"<<endl;
	Replace(G,'d','k');
	GL_Display(G);
	cout<<endl;

	cout<<"在k后面插入x"<<endl;
	GL_Insert(G,'k','x');
    GL_Display(G);
	cout<<endl;

	cout<<"删除表中数据'k'"<<endl;
	GL_Delete(G,'k');
	GL_Display(G);
	cout<<endl;

	return 0;
}

测试结果

其中测试的表是

(a,(b,c,d),(d,l),d,p))

表的深度为:2
表的长度为:5
遍历表:(a,(b,c,d),(d,l),d,p)
表的表头为:a
表尾为:((b,c,d),(d,l),d,p)
将原表中的d全部替换成k
(a,(b,c,k),(k,l),k,p)
在k后面插入x
插如成功
插如成功
插如成功
(a,(b,c,k,x),(k,x,l),k,x,p)
删除表中数据'k'
(a,(b,c,x),(x,l),x,p)
Press any key to continue


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值