广义表的基本操作

Posted helenandyoyo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了广义表的基本操作相关的知识,希望对你有一定的参考价值。

#include<iostream>
#include<string>
using namespace std;

typedef enumATOM,LISTElemTag;	//ATOM==0:原子,LIST==1:子表
typedef char AtomType;	//原子值域类型

class GLNode
friend class GList;
private:
	ElemTag tag;	//tag==ATOM表示原子结点,tag==LIST表示表结点
	union
	
		AtomType atom;	//atom是原子的值域
		struct
			GLNode* hp;	
			GLNode* tp;
		ptr;	//ptr是表结点的指针域,ptr.hp和ptr.tp分别指向表头和表尾
	;//union
;//GLNode

class GList
public:
	void sever(string &SS,string &hsub);	//将非空串SS分割成两部分:
											//hsub是第一个','之前的子串,SS为之后的串
	void CreateGList(GLNode *&L,string S);	//S是广义表的书写形式串,由S创建广义表L
	void Traverse_GL(GLNode *L);			//输出广义表L
	void CopyGList(GLNode *&T,GLNode *L);	//由广义表L复制得到广义表T
	int GListDepth(GLNode *L);				//求广义表L的深度
	int GListLength(GLNode *L);				//求广义表L的长度,即元素个数
	void GetHead(GLNode *&M,GLNode *L);		//取广义表的表头,用M返回
	void GetTail(GLNode *&M,GLNode *L);		//取广义表的表尾,用M返回
	void InsertFirst_GL(GLNode *&L,GLNode *e);//插入元素e作为广义表的第一元素
	void DeleteFirst_GL(GLNode *&L,GLNode *&e);//删除广义表L的第一元素,并用e返回
;

void GList::sever(string &SS,string &hsub)

	unsigned int i,k;//k记尚未配对的左括号个数
	string ch="";
	for(i=0,k=0;i<SS.length()&&ch!=","||k!=0;i++)
	
		ch=SS.substr(i,1);
		if(ch=="(")	k++;
		else if(ch==")") k--;
	//for
	if(i<SS.length())
	
		hsub=SS.substr(0,i-2+1);//i-2是因为for循环时i最后都增加了1
		SS=SS.substr(i,SS.length()-i+1);
	//if
	else
	
		hsub=SS.substr();
		SS.clear();
	//else
//sever

/*广义表字符串S可能的两种情况:(1)S="()" (带括弧的空白串)                  */
/*(2)S="(a1,a2,..,an),其中ai是S的子串,可以为原子结点,也可以是子表"       */
/*两种递归算法:(1)把广义表分解为表头和表尾两部分,(2)将表看成是n个并列子表*/
void GList::CreateGList(GLNode *&L,string S)

	GLNode *p=NULL,*q=NULL;
	string SS,hsub;
	if(S=="()")	//创建空表
		L=NULL;
	else
	
		L=new GLNode;
		if(!L)
			exit(-1);
		if(S.length()==1)//单原子
		
			L->tag=ATOM;
			L->atom=S[0];
		//if
		else			//多字符串S
		
			L->tag=LIST;//定义为表结点
			p=L;q=L;
			SS=S.substr(1,S.length()-2);//脱外层括号
			while(!SS.empty())
			
				sever(SS,hsub);	//从SS中分离出表头串
				CreateGList(p->ptr.hp,hsub);//创建表头子表
				if(!SS.empty())//表尾不空
				
					if(!(p=new GLNode))	//使指针p指向新的分配空间
						exit(-1);
					p->tag=LIST;	//	p为表的下一个表结点
					q->ptr.tp=p;
                    q=p;
				//if	
			//while
			q->ptr.tp=NULL;
		//else
	//else
//CreateGList

void GList::Traverse_GL(GLNode *L)

	GLNode *p=NULL;
	if(!L)//L为空表
		cout<<"()";
	else if(L->tag==ATOM)//遇到原子结点
	
		cout<<L->atom;
	//if
	else
	
		p=L;
		cout<<"(";
		while(p)
		
			Traverse_GL(p->ptr.hp);//遍历子表
			p=p->ptr.tp;
			if(p)
				cout<<",";
		//while
		cout<<")";
	//else
//Traverse_GL

/*复制一个广义表只要分别复制其表头和表尾,然后合成即可*/
void GList::CopyGList(GLNode *&T,GLNode *L)

	//if(T->tag==ATOM||T->tag==LIST)	//将原始表T清空
		//delete T;T=NULL;//if	
	if(!L)	//表L为空表
		T=NULL;
	else	
	
		if(!(T=new GLNode))
			exit(-1);
		T->tag=L->tag;
		if(L->tag==ATOM)	//原子结点
			T->atom=L->atom;
		else
		
			CopyGList(T->ptr.hp,L->ptr.hp);	//复制表头
			CopyGList(T->ptr.tp,L->ptr.tp);	//复制表尾
		//else
	//else
//CopyGList

/*广义表的深度定义为广义表中括弧的重数*/
/*基本项:DEPTH(L)=1	当L为空表时   */
/*        DEPTH(L)=0    当L为原子时   */
/*        DEPTH(L)=1+MaxDEPTH(ai)   */
int GList::GListDepth(GLNode *L)

	int max,dep=0;
	GLNode *p=L;
	if(!L)
		return 1;
	if(L->tag==ATOM)	//原子结点
		return 0;
	for(max=0;p;p=p->ptr.tp)
	
		dep=GListDepth(p->ptr.hp);	//子表深度
		if(max<dep)
			max=dep;
	//for
	return (max+1);
//GListDepth

int GList::GListLength(GLNode *L)

	int len=0;
	if(!L)
		return 0;
	else
	
		GLNode *p=L;
		while(p)
		
			len++;
			p=p->ptr.tp;
		//while
	//else
	return len;
//GListLength

void GList::GetHead(GLNode *&M,GLNode *L)

	CopyGList(M,L->ptr.hp);
//GetHead

void GList::GetTail(GLNode *&M,GLNode *L)

	CopyGList(M,L->ptr.tp);
//GetTail

void GList::InsertFirst_GL(GLNode *&L,GLNode *e)

	GLNode *p=e;
	while(p->ptr.tp)
	
		p=p->ptr.tp;
	//while
	p->ptr.tp=L;
	L=e;
//InsertFirst_GL

void GList::DeleteFirst_GL(GLNode *&L,GLNode *&e)

	GLNode *p=L;
	L=L->ptr.tp;
	p->ptr.tp=NULL;
	CopyGList(e,p);
	delete p;
	p=NULL;
//DeleteFirst_GL

void main()

	GLNode *L;
	GList glist;
	string S;
	cout<<"输入广义表L的字符串S:";
	cin>>S;
	glist.CreateGList(L,S);
	cout<<"\\n"<<"------------输出广义表L------------"<<endl;
	glist.Traverse_GL(L);cout<<endl;
	cout<<"广义表L的深度Dep:";
	cout<<glist.GListDepth(L)<<endl;
	cout<<"广义表L的长度Len:";
	cout<<glist.GListLength(L)<<endl;
	GLNode *M;
	cout<<"广义表L的表头M:";
	glist.GetHead(M,L);
	glist.Traverse_GL(M);cout<<endl;
	GLNode *N;
	cout<<"广义表L的表尾N:";
	glist.GetTail(N,L);
	glist.Traverse_GL(N);cout<<endl;

	GLNode *T;
	glist.CopyGList(T,L);
	cout<<"\\n"<<"------由广义表L复制得到广义表T-----"<<endl;
	glist.Traverse_GL(T);cout<<endl;
	
	GLNode *e;
	string S_e;
	cout<<"\\n"<<"输入元素e的字符串形式S_e:";
	cin>>S_e;
	glist.CreateGList(e,S_e);
	cout<<"输出元素e:";
	glist.Traverse_GL(e);cout<<endl;
	glist.InsertFirst_GL(L,e);
	cout<<"-----将元素e插入广义表L之首后的广义表L-----"<<endl;
	glist.Traverse_GL(L);cout<<endl;

	GLNode *ee;
	glist.DeleteFirst_GL(L,ee);
	cout<<"\\n"<<"输出广义表L删除的第一个元素ee:";
	glist.Traverse_GL(ee);
	cout<<"\\n"<<"------输出删除第一个元素后的广义表L-------"<<endl;
	glist.Traverse_GL(L);

	
//main

以上是关于广义表的基本操作的主要内容,如果未能解决你的问题,请参考以下文章

数据结构29:广义表的长度和深度

广义表的概念及存储表示

广义表

广义表

广义表及其推广

广义表的实现