广义表的实现(c++实现)

本文要点:

1.广义表的存储结构

2.广义表的简单实现,包括:构造、拷贝构造、赋值运算符重载、广义表的大小Size、深度Depth以及输出函数


广义表是非线性的结构,是一种线性表的推广,它由n个元素组成有限序列。广义表的定义是递归的。

一、广义表的存储结构

由于广义表中的数据元素可以有不同结构,采用顺序表的结构是很难实现的,因此通常采用链式存储结构,每个元素可用一个节点表示,一个结点有可能是头结点_head,有可能是值结点_value,也有可能是子表项_sub(递归)。如广义表A、B、C、D、E是这样定义:

A = ()

B = (a,b)

C = (a,b,(c,d))

D = (a,b,(c,d),(e,(f),h))

来看看这个表的存储结构:


从上图我们也可以很清晰的看到,一个结点的内容有三种,并且只要遇到 “(” 就有子表项,遇到 “)” 该子表项结束。因此要用链表的方式实现广义表,我们首先要定义出结点内容:

enum TYPE
{
	HEAD_TYPE,	//表头
	VALUE_TYPE,	//值
	SUB_TYPE,	//子表
};

struct GeneralizedNode
{
	GeneralizedNode(TYPE type,const char& value=0)
		:_type(type)
		,_next(NULL)
		,_sublink(NULL)
	{
		_value = value;
	}

	TYPE _type;		//类型
	GeneralizedNode* _next;	//指向下一个表项
	union
	{
		char _value;
		GeneralizedNode* _sublink;	//指向子表头
	};
	//除头结点外,剩下的节点中每个结点有可能是value也可能是sub,因此用联合
};


二、接下来就是广义表的实现部分了:

class GeneralizedList
{
	typedef GeneralizedNode Node;
public:
	GeneralizedList()
		:_head(NULL)
	{}

	GeneralizedList(const char* str)
		:_head(NULL)
	{
		_head = _CreatList(str);
	}
	
	GeneralizedList(const GeneralizedList& g)	//拷贝构造
	{
		_head = _copy(g._head);
	}

	~GeneralizedList()
	{
		Destory(_head);
	}

	GeneralizedList& operator=(const GeneralizedList& g)
	{
		//_head = _assignment(g);
		if (this != &g)
		{
			GeneralizedList tmp(g);
			std::swap(_head,tmp._head);
		}
		return *this;
	}

	size_t Size()
	{
		return _size(_head);
	}
	size_t Depth()
	{
		return _depth(_head);
	}
	void Print()
	{
		_print(_head);
	}
protected:
	bool Judge(const char& value)
	{
		if ((value >= '0' && value <= '9') ||
			(value >= 'a' && value <= 'z') ||
			(value >= 'A' && value <= 'Z') )	
			return true;
		else
			return false;
	}
	Node* _CreatList(const char*& str)
	{
		assert(*str == '(');
		Node* head = new Node(HEAD_TYPE,*str);
		Node* prev = head;
		head->_type = HEAD_TYPE;
		++str;
		while (*str)
		{
			if (Judge(*str))		//有效值项
			{
				Node* node = new Node(VALUE_TYPE,*str);
				prev->_next = node;
				prev = prev->_next;

				++str;
			}
			else if (*str == '(')		//有子表项
			{
				Node* node = new Node(SUB_TYPE,*str);
				prev->_next = node;
				prev = prev->_next;
				prev->_sublink = _CreatList(str);
				++str;
			}
			else if (*str == ')')
			{
				prev->_next = NULL;

				++str;
				return head;
			}
			else
				++str;
		}
		return head;
	}
	Node* _copy(Node* copyhead)
	{
		assert(copyhead);
		Node* newhead = new Node(HEAD_TYPE,copyhead->_value);	//新表的头
		Node* prev = newhead;
		Node* cur = copyhead->_next;
		while (cur)
		{
			if (cur->_type == VALUE_TYPE)	//拷贝值结点
			{
				Node* tmp = new Node(VALUE_TYPE,cur->_value);
				prev->_next = tmp;
				prev = prev->_next;
				cur = cur->_next;
			}
			else if (cur->_type == SUB_TYPE)		//拷贝子表
			{
				Node* tmp = new Node(SUB_TYPE);
				prev->_next = tmp;
				prev = prev->_next;
				tmp->_sublink = _copy(cur->_sublink);
				cur = cur->_next;
			}
			else
				cur = cur->_next;
		}
		return newhead;
	}
	void Destory(Node* head)
	{
		Node* cur = head;
		while (cur)
		{
			Node* del = cur;
			if (cur->_type == SUB_TYPE)
			{
				Destory(cur->_sublink);
			}
			cur = cur->_next;
			delete[] del;
		}
	}
	Node* _assignment(const GeneralizedList& g)
	{
		assert(g._head);
		if (this != &g)
		{
			Node* newhead = new Node(HEAD_TYPE,g._head->_value);
			Destory(_head);
			_head = newhead;
		}
		return _head;
	}
	size_t _size(Node* head)	//表内有效值的个数
	{
		Node* cur = head;
		size_t count = 0;
		while (cur)
		{
			if (cur->_type == VALUE_TYPE)
			{
				count++;
			}
			else if (cur->_type == SUB_TYPE)
			{
				count += _size(cur->_sublink);
			}
			cur = cur->_next;
		}
		return count;
	}
	size_t _depth(Node* head)	//表的最大深度
	{
		Node* cur = head;
		size_t maxdepth = 1;
		while(cur)
		{
			size_t depth = 1;
			if (cur->_type == SUB_TYPE)
			{
				depth += _depth(cur->_sublink);
				if (depth > maxdepth)
				{
					maxdepth = depth;
				}
			}
			cur = cur->_next;
		}
		return maxdepth;
	}
	void _print(Node* head)
	{
		assert(head);
		Node* cur = head;
		while (cur)
		{
			if (cur->_type == VALUE_TYPE)
			{
				cout<<cur->_value;
				if (cur->_next != NULL)
				{
					cout<<",";
				}
				cur = cur->_next;
			}
			else if (cur->_type == SUB_TYPE)
			{
				_print(cur->_sublink);
				if (cur->_next != NULL)
				{
					cout<<",";
				}
				cur = cur->_next;
			}
			else
			{
				cout<<"(";
				cur = cur->_next;
			}
		}
		cout<<")";
	}
protected:
	Node* _head;
};












评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值