广义表

什么是广义表呢?

广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列。

广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表。

如:

<1> A = ()

<2> B = (a,b)

<3> C = (a,b,(c,d))

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


广义表_第1张图片

在广义表节点时,应注意一下几点:

(1)由图看出,节点存在三种类型。头,值,子表。

(2)指向下一个节点的指针。

(3)因广义表中允许表中有表。需要一个指向子表的指针。

//节点结构
enum Type
{
	HEAD,//广义表表头
	VALUE,//值
	SUB,//子表
};

class GeneralizedNode//节点
{
public:
	GeneralizedNode(Type type = HEAD,char value = 0)
		:_type(type)
		,_next(NULL)
	{
		if(type == VALUE)
		{
			_value = value;
		}
		if(type == SUB)//子表初始化
		{
			_subLink = NULL;
		}
	}
public:
	Type _type;//类型
	GeneralizedNode* _next;//指向下一个节点
	union
	{
		char _value;//节点值
		GeneralizedNode* _subLink;//指向子表的头
	};
};


在定义广义表之前,先来了解一下关于广义表的几个概念:

(1)广义表的节点的个数:广义表中所有节点的个数(包括子表节点)。

(2)广义表的长度:只看表层。

(3)广义表的深度:子表中深度最大的一个。

如: C = (a,b,(c,d))           长度为3,深度为2

     D = (a,b,(c,d),(e,(f),h)) 长度为4,深度为3


//广义表
class Generalized
{
public:
	Generalized()//无参构造函数
		:_head(new GeneralizedNode(HEAD))
	{}
public:
	bool IsValue(char ch)//判断是否为有效字符
	{
		if((ch>='0')&&(ch<='9')||((ch>='a')&&(ch<='z'))||((ch>='A')&&(ch<='Z')))
		{
			return true;
		}
		return false;
	}
public:
	GeneralizedNode* _Generalized(const char* &str)
	                                               
	{
		assert(str && *str == '(');
			str++;
		GeneralizedNode* head = new GeneralizedNode(HEAD);//创建头
		GeneralizedNode* cur = head;
		while(*str)
		{
			if(IsValue(*str))
			{
				cur->_next = new GeneralizedNode(VALUE,*str);
				cur = cur->_next;
				str++;
			}
			else if(*str == '(')
			{
				cur->_next = new GeneralizedNode(SUB);
				cur = cur->_next;
				cur->_subLink = _Generalized(str);//遇到子表递归
			}
			else if(*str == ')')//递归终止条件
			{
				str++;
				return head;
			}
			else
			{
				str++;
			}
		}
		assert(false);//强制判断
		return head;
	}
	void _Print(GeneralizedNode* head)//打印
	{
		GeneralizedNode* cur = head;
		while(cur)
		{
			if(cur->_type == HEAD)//遇到头
			{
				cout<<"(";
			}
			else if(cur->_type == VALUE)
			{
				cout<<cur->_value;
				if(cur->_next)
				{
					cout<<",";
				}
			}
			else
			{
				_Print(cur->_subLink);//遇到子表递归
				if(cur->_next)
				{
					cout<<",";
				}
			}
			cur = cur->_next;
		}
		cout<<")";
	}

	size_t _Size(GeneralizedNode* head)//节点的个数
	{
		GeneralizedNode* cur = head;
		size_t count = 0;
		while(cur)
		{
			if(cur->_type == VALUE)
			{
				count++;
			}
			else if(cur->_type == SUB) //子表递归
			{
				count = count + _Size(cur->_subLink);//所有节点的个数
			}
			cur = cur->_next;
		}
		return count;
	}

	size_t _Length(GeneralizedNode* head)//长度,只看表层,子表长度为1,元素长度为1
	{
		GeneralizedNode* cur = head;
		size_t len = 0;
		if(head == NULL)
			return 0;
		while(cur)
		{
			if(cur->_type == VALUE)
			{
				len++;
			}
			else if(cur->_type == SUB)
			{
				len++;
			}
			cur = cur->_next;
		}
		return len;
	}

	size_t _Depth(GeneralizedNode* head)//深度 需要对每个子表求深度,找最大的
	{
		GeneralizedNode* cur = head;
		size_t depth = 0;
		size_t max = 0;
		while(cur)
		{
			if(cur->_type == SUB)
			{
				depth = _Depth(cur->_subLink);//子表递归
				if(depth > max)//大于目前最大,更换
				{
					max = depth;
				}
			}
			cur = cur->_next;
		}
		return max+1;
	}
	void _Destory(GeneralizedNode* head)
	{
		GeneralizedNode* cur = head;
		while(cur)
		{
			GeneralizedNode* del = cur;
			cur = cur->_next;
			if(del->_type == SUB)
			{
				_Destory(del->_subLink);
			}
			delete del;
		}
	}

	GeneralizedNode* _Copy(GeneralizedNode* head)//拷贝构造
	{
		GeneralizedNode* cur = head->_next;
		GeneralizedNode* newHead = new Generalized(HEAD);
		while(cur)
		{
			if(cur->_type == VALUE)//若为值,连接在新表头的后边
			{
				GeneralizedNode* newCur = newHead;
				newCur->_next = new GeneralizedNode(VALUE,cur->_value);
				newCur = newCur->_next;
			}
			else if(cur->_type == SUB)//若为子表
			{
				newCur->_next = new GeneralizedNode(SUB);
				newCur = newCur->_next;
				newCur->_subLink = _Copy(cur->_subLink);//递归
			}
			cur = cur->_next;
		}
		return newHead;
	}
public:
	~Generalized()//析构函数
	{
		_Destory(_head);
		_head = NULL;
	}
	Generalized(const Generalized& g)
	{
		_head = _Copy(g._head);
	}
	Generalized& operator=(const Generalized& g)
	{
		if(this != &g)//是否自复制
		{
			_Destory(_head);//释放原来的空间
			_head = _Copy(g._head);
		}
		return *this;
	}
	//由于上述的赋值函数可能会不成功,所以先开辟空间保存
	Generalized& operator=(const Generalized& g)
	{
		if(this != &g)
		{
			GeneralizedNode* tmp = _Copy(g._head);
			_Destory(_head);
			_head = tmp;
		}
		return *this;
	}
	//现代写法
	Generalized& operator=(const Generalized g)//出了作用域后,g自动销毁
	{
		swap(_head,g._head);
		return *this;
	}
public:
	Generalized(const char* str)//以链表形式存储
	{
		_head = _Generalized(str);
	}
	void Print()//打印
	{
		_Print(_head);
		cout<<endl;
	}
	size_t Size()//节点个数
	{
		return _Size(_head);
	}
	size_t Length()//表的长度
	{
		return _Length(_head);
	}
	size_t Depth()
	{
		return _Depth(_head);
	}
protected:
	GeneralizedNode* _head;
};

测试函数:

void Test()
{
     Generalized g1("(a,b,(e,f),(c,d))");
     Generalized g2("(a,b,(c,d))");
     Generalized g3("(a,b,(c,d),(e,(f),h))"); 
     g2.Print();
     size_t ret1 = g2.Size();
     size_t ret2 = g1.Length();
     size_t ret3 = g3.Depth();
     
     Generalized g4(g1);
     g4.Print();

     Generalized g5;
     g5 = g3;
     g3.Print();
     cout<<ret1<<endl;
     cout<<ret2<<endl;
     cout<<ret3<<endl;
  }

测试结果:

                 广义表_第2张图片

本文出自 “一起去看星星” 博客,转载请与作者联系!

你可能感兴趣的:(广义表)