C++实现广义表

定义:

广义表是n(n≥0)个元素a1,a2,…,ai,…,an的有限序列。

  其中:
  ①ai--或者是原子或者是一个广义表。
  ②广义表通常记作:
  Ls=( a1,a2,…,ai,…,an)。
  ③Ls是广义表的名字,n为它的长度。
  ④若ai是广义表,则称它为Ls的子表。
  注意:
  ①广义表通常用圆括号括起来,用逗号分隔其中的元素。
  ②为了区分原子和广义表,书写时用大写字母表示广义表,用小写字母表示原子。
  ③若广义表Ls非空(n≥1),则al是LS的表头,其余元素组成的表(a1,a2,…,an)称为Ls的表尾。

  ④广义表是递归定义的

画图举例:


代码实现:

#include <iostream>

using namespace std;

//表示广义表的结点类型
enum NodeType
{
	HEAD_TYPE,//头结点类型
	VALUE_TYPE,//值结点类型
	SUB_TYPE//子表类型
};

//表示广义表结点的结构体
struct GeneraListNode
{
	NodeType _type;//结点类型
	GeneraListNode *_next;//存放结点的下一个元素的地址

	//一个结点要么是值结点要么是子表,故用联合体来存放节省一定的空间
	//若是值结点则存放的是值,是子表结点的话存放的是子表结点头结点的地址
	union{
		char _value;
		GeneraListNode *_subLink;
	};

	GeneraListNode(NodeType type = HEAD_TYPE, char value = '\0')
		:_type(type)
		,_next(NULL)
	{
		if (type == VALUE_TYPE)
		{
			_value = value;
		}else if(type == SUB_TYPE)
		{
			_subLink = NULL;
		}

	}

};

class GeneraList
{
private:
	GeneraListNode *_link;//用来存放广义表头结点地址
public:
	GeneraList(const char *str)
		:_link(NULL)
	{
		_CreateGeneraList(_link, str);//根据指定序列创建广义表
	}

	~GeneraList()
	{}
public:
	void Print();//对外提供的打印广义表的接口
	int Size();//广义表中值结点的数目的对外获取接口
	int Depth();//广义表的最深层次的对外获取接口
private:
	void _CreateGeneraList(GeneraListNode *& link, const char *& str);
	bool _IsValue(const char ch);//判断指定字符是否为值结点所允许的类型
	int _Size(GeneraListNode *head);//计算广义表中值结点的数目的实现
	int _Depth(GeneraListNode *head);//计算广义表的最深层次的实现
	void _Print(GeneraListNode *link);//打印广义表的接口的底层实现
};

//创建广义表
void GeneraList::_CreateGeneraList(GeneraListNode *& link, const char *& str)
{
	//广义表最前端有一个头结点,用来记录实现广义表链表的首地址
	//故每次调用该创建广义表的函数首先创建一个头结点
	GeneraListNode* head = new GeneraListNode(HEAD_TYPE, NULL);
	head->_next = NULL;
	link = head;
	GeneraListNode* cur = link;//用来记录创建广义表链表时当前创建出的结点位置游标指针
	str++;//将广义表序列后移,相当于跳过了'('
	
	while(*str != '\0')
	{
		if(_IsValue(*str)){//如果当前扫描到的字符是值
			//创建一个值结点
			GeneraListNode* newNode = new GeneraListNode(VALUE_TYPE, *str);
			newNode->_next = NULL;
			cur->_next = newNode;//将该值结点加入到链表中
			cur = cur->_next;//游标后移
			str++;//将广义表序列后移
		}else if(*str == '('){//如果扫描到'('创建子表结点
			GeneraListNode* subLink = new GeneraListNode(SUB_TYPE, NULL);
			subLink->_next = NULL;
			cur->_next = subLink;//将子表结点加入到链表中
			cur = cur->_next;
			_CreateGeneraList(cur->_subLink, str);//递归创建子表
		}else if(*str == ')'){
			str++;
			return;//若扫描到')'表示广义表创建结束
		}else{
			str++;//空格等其他无效字符跳过
		}
	}
}

int GeneraList::Size()
{
	return _Size(_link);
}

//计算广义表值结点的个数
int GeneraList::_Size(GeneraListNode *head)
{
	int size = 0;
	GeneraListNode *cur = head;
	while(cur != NULL){
		if(cur->_type == VALUE_TYPE){
			++size;//遇到值结点则将size加一
		}else if(cur->_type == SUB_TYPE){
			size += _Size(cur->_subLink);//遇到子表进行递归
		}
		cur = cur->_next;
	}
	return size;
}

int GeneraList::Depth()
{
	return _Depth(_link);
}
int GeneraList::_Depth(GeneraListNode *head)
{
	int depth = 1,maxDepth = 1;//depth表示当前表的深度,maxDepth表示目前最大的深度
	GeneraListNode *cur = head;
	while(cur != NULL){
		if(cur->_type == SUB_TYPE){
			depth += _Depth(cur->_subLink);
		}
		if(depth > maxDepth){//更新最大深度
			maxDepth = depth;
			depth = 1;//将当前深度复位
		}
		cur = cur->_next;
	}
	return maxDepth;
}

void GeneraList::Print()
{
	_Print(_link);
	cout<<endl;
}

//打印广义表
void GeneraList::_Print(GeneraListNode *link)
{
	GeneraListNode *cur = link;//遍历广义表的游标
	while(cur != NULL){
		if(cur->_type == VALUE_TYPE){
			cout<<cur->_value;
			if(cur->_next != NULL)
			{
				cout<<',';
			}
		}else if(cur->_type == HEAD_TYPE){
			cout<<"(";
		}else if(cur->_type == SUB_TYPE){
			_Print(cur->_subLink);//遇到子表递归打印
			if(cur->_next != NULL)//如果打印完子表后广义表未结束则打印','
			{
				cout<<",";
			}
		}
		cur = cur->_next;
	}
	cout<<")";
}

bool GeneraList::_IsValue(const char ch)
{
	if(ch >= 'a' && ch <= 'z' ||
	   ch >= 'A' && ch <= 'Z' ||
	   ch >= '0' && ch <= '(')
	{
		return true;
	}
	return false;
}

测试代码

#include"GeneraList.hpp"

//测试空表
void Test1()
{
	GeneraList genList("()");
	genList.Print();
	cout<<"Size is :"<<genList.Size()<<endl;
	cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//测试单层表
void Test2()
{
	GeneraList genList("(a,b)");
	genList.Print();
	cout<<"Size is :"<<genList.Size()<<endl;
	cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//测试双层表
void Test3()
{
	GeneraList genList("(a,b,(c,d))");
	genList.Print();
	cout<<"Size is :"<<genList.Size()<<endl;
	cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//测试多层表
void Test4()
{
	GeneraList genList("(a,b,(c,d),(e,(f),h))");
	genList.Print();
	cout<<"Size is :"<<genList.Size()<<endl;
	cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}
//测试多层空表
void Test5()
{
	GeneraList genList("(((),()),())");
	genList.Print();
	cout<<"Size is :"<<genList.Size()<<endl;
	cout<<"Depth is :"<<genList.Depth()<<endl<<endl;
}

int main()
{
	Test1();
	Test2();
	Test3();
	Test4();
	Test5();
	return 0;
}

运行结果


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值