Generalized------广义表

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

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

<1>A=();

<2>B=(a, b);

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

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

<5>E = (((),()))

那么广义表如何实现呢?

我们使用递归来实现它~~~~

#pragma once;
#include<iostream>
using namespace std;
#include<assert.h>

enum Type
{
	HEAD,
	VALUE,
	SUB,
};

struct GeneralizedNode
{
	Type _type;                     //结点类型
	GeneralizedNode* _next;
	union
	{
		char _value;                //若为值类型结点,则存储值
		GeneralizedNode* _sublink;  
	};

	GeneralizedNode(Type type = HEAD,char value=0)
		:_type(type)
		, _next(NULL)
	{
		if (_type == VALUE)
		{
			_value = value;
		}
		else if (_type == SUB)
		{
			_sublink = NULL;
		}
	}
};

class Generalized
{
public:
	Generalized()
	    :_head(NULL)
	{}

	Generalized(const char* str)
		:_head(NULL)
	{
		_head = _CreateLized(str);   
	}

	Generalized(const Generalized& g)
	{
		_head = _Copy(g._head);
	}

	Generalized& operator=(const Generalized& g)
	{
		if (_head != g._head)
		{
			GeneralizedNode* cur = _head;
			_Destory(_head);
			_head = _Copy(g._head);
			return *this;
		}
	}

	~Generalized()
	{
		_Destory(_head);
	}
public:
	void Print()
	{
		_Print(_head);
		cout << endl;
	}
	size_t Size()
	{
		size_t count = _Size(_head);
		return count;
	}

	size_t Depth()
	{
		size_t dep = _Depth(_head);
		return dep;
	}

protected:
	//创建表
	GeneralizedNode* _CreateLized(const char*& str)//传参用引用是为了防止str在退出一层
	{                                              //递归时发生回退
		assert(str&&*str == ‘(‘);     //若当前str是不为‘(’,则传参错误
		str++;                       

		GeneralizedNode* head = new GeneralizedNode(HEAD);
		GeneralizedNode* cur = head;
		while (*str != ‘\0‘)
		{
			if (_Isvalue(*str))
			{
				GeneralizedNode* tmp = new GeneralizedNode(VALUE, *str);
				cur->_next = tmp;
				cur = cur->_next;
				str++;
				continue;
			}
			else if (*str == ‘(‘)   //遇到子表
			{
				GeneralizedNode* sub = new GeneralizedNode(SUB);
				cur->_next = sub;
				cur = cur->_next;
				sub->_sublink = _CreateLized(str);  //进入递归创建子表
				continue;
			}
			else if (*str == ‘)‘)  //一个表的结束
			{
				str++;
				return head;
			}
			else
			{
				str++;
				continue;
			}
			assert(false);  //强制判断程序是否出错
			return head;
		}
	}

	//判断当前值是否为有效值
	bool _Isvalue(const char c)
	{
		if ((c <= ‘9‘&&c >= ‘0‘) || (c <= ‘z‘&&c >= ‘a‘) || (c <= ‘Z‘&&c >= ‘A‘))
		{
			return true;
		}
		else
		{
			return false;
		}
	}

	//拷贝一个表
	GeneralizedNode* _Copy(GeneralizedNode* head)
	{
		GeneralizedNode* Head = new GeneralizedNode(HEAD);
		//_head = Head;
		GeneralizedNode* cur = head->_next;
		GeneralizedNode* tmp = Head;
		while (cur)
		{
			if (cur->_type == VALUE)
			{
				tmp->_next = new GeneralizedNode(VALUE, cur->_value);
				cur = cur->_next;
				tmp = tmp->_next;
			}
			else if (cur->_type == SUB)
			{
				tmp->_next = new GeneralizedNode(SUB);
				//cur = cur->_next;
				tmp = tmp->_next;
				tmp->_sublink = _Copy(cur->_sublink);  //进入拷贝表的递归
				cur = cur->_next;
			}
		}
		return Head;
	}

	//打印表
	void _Print(GeneralizedNode* head)
	{
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type == HEAD)
			{
				cout << "(" << " ";
				cur = cur->_next;
				continue;
			}
			else if ((cur->_type == VALUE) && (cur->_next != NULL))
			{
				cout << cur->_value << " " << ",";
				cur = cur->_next;
				continue;
			}
			else if ((cur->_type == VALUE) && (cur->_next == NULL))//遇到一个表的最后一个节点
			{
				cout << cur->_value << " ";
				cur = cur->_next;
				continue;
			}
			else if (cur->_type == SUB)
			{
				_Print(cur->_sublink);                //进入打印表的递归
				cur = cur->_next;
				if (cur != NULL)      //说明此时的表并不是最外层的表,需要打印‘,’
				{
				   cout << ",";
				}
				continue;
			}
		}
		if (cur == NULL)
		{
			cout << ")";
			return;
		}
	}

	//销毁表
	void _Destory(GeneralizedNode* head)
	{
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type  == SUB)
			{
				_Destory(cur->_sublink);  //进入销毁表的递归
			}
			GeneralizedNode* del = cur;
			cur = cur->_next;
			delete del;
		}
		return;
	}

	//求表的大小
	size_t _Size(GeneralizedNode* head)
	{
		size_t count = 0;
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type == VALUE)
			{
				count++;
				cur = cur->_next;
				continue;
			}
			if (cur->_type == SUB)
			{
				count += _Size(cur->_sublink); //进入递归
				cur = cur->_next;
				continue;
			}
			cur = cur->_next;
		}
		return count;
	}

	//求表的深度
	size_t _Depth(GeneralizedNode* head)
	{
		assert(head);
		size_t dep = 1;
		size_t Dep = 0;
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type == SUB)
			{
				dep += _DepthSUB(cur->_sublink); 
			}
			cur = cur->_next;
			if (Dep < dep)   //用Dep来保存最深的深度
			{
				Dep = dep;
				dep = 1;
			}
		}

		return Dep;
	}
	//求子表长度
	size_t _DepthSUB(GeneralizedNode* sub)
	{
		GeneralizedNode* cur = sub;
		size_t dep = 1;
		while (cur)
		{
			if (cur->_type == SUB)
			{
				dep = dep + _DepthSUB(cur->_sublink);
			}
			cur = cur->_next;
		}
		return dep;
	}

protected:
	GeneralizedNode* _head;
};

广义表的函数都用了递归,所以会比较绕。小伙伴们好好看,不懂可以来交流啊。写的不好多多指教~~~~

时间: 2024-11-05 16:36:12

Generalized------广义表的相关文章

c++数据结构之广义表

最近学习了广义表,我们知道广义表也是一种线性表,而顾名思义广义表就是不止一个表,下面来举个栗子: A=( ) B=(1 , 2,3) C=(1 ,2 ,3, ( a , b ,c) ) D=(1, 2, 3, (a,( b,c),d),4) 以上A,B,C,D都是广义表,只不过深度不一样,也就是括号的对数不一样,A是个特殊的广义表,即空表.B里面有三个元素,C里面有6个元素,包括一个子表(a,b,c),C也同理,只不过多了一层子表.由此可总结为一句话:表里有表 这样看可能不太直观,下面以广义表C

c++实现广义表

广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列. 广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表. <1> A = () <2> B = (a,b) <3> C = (a,b,(c,d)) <4> D = (a,b,(c,d),(e,(f),h)) <5> E = (((),())) 如下图所示: 广义表主要使用递归实现,表与表之间使用链式结构来存储.下面就来看看代码怎样实现的: #pragma once #i

广义表 的实现

广义表是非线性结构,其定义是递归的. 以下给出几种简单的广义表模型: 由上图我们可以看到,广义表的节点类型无非head.value.sub三种,这里设置枚举类型,利用枚举变量来记录每个节点的类型: enum  Type { HEAD,   //头节点 VALUE,  //值节点 SUB,    //子表节点 }; 每个节点都有自己的类型以及next指针,除此之外,如果该节点是VALUE类型还要分配空间存储该节点的有效值:但是若该节点是SUB类型,就需定义一个指针指向子表的头. 这里我们可以用联合

初试-&gt;广义表

广义表:又称列表)是一种非线性的数据结构,是线性表的一种推广.即广义表中放松对表元素的原子限制,容许它们具有其自身结构.它被广泛的应用于人工智能等领域的表处理语言LISP语言中.在LISP语言中,广义表是一种最基本的数据结构,就连LISP 语言的程序也表示为一系列的广义表. 广义表是n (n>=0)个元素a1,a2,a3,-,an的有限序列,其中ai或者是原子项,或者是一个广义表.通常记作LS=(a1,a2,a3,-,an).LS是广义表的名字,n为它的长度.若ai是广义表,则称它为LS的子表.

【代码】C++实现广义表及其测试用例

广义表是我第一次用递归接触链式的数据结构,其结构如下: HEAD->VAL->VAL->LINK(->HEAD.....)->VAL->......     在这里,我们的头结点与link节点是不存储数据的,由此我们便可以定义出节点的数据结构: typedef int DataType; enum NodeType//枚举类型定义节点类型 { HEAD, VALUE, SUB, }; struct GeneralizedNode { public: Generalize

广义表总结

/**********************          WZ  ASUST 2016 表的实现与表头表尾问题 缺函数:找值 **********************/ #include<iostream> #include<assert.h> #include<string> using namespace std;   //实现广义表的结构 // 节点的类型:来代替直接写3类 结构体 enum Type//枚举类型 {     HEAD,     VAL

广义表的递归实现

广义表的定义 广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列. 广义表的定义是递归的,因为在表的描述中又得到了表,允许表中有表. 例如 <1> A = () <2> B = (a,b) <3> C = (a,b,(c,d)) <4> D = (a,b,(c,d),(e,(f),h)) <5> E = (((),()) 广义表的节点结构定义: enum Type { HEAD,//头结点 VALUE,//数据 SUB,//子表

广义表的C++简单实现

广义表是数据结构中非常关键的一部分,它的学习对于树和二叉树有很大的起承作用.那么,它是怎么实现的呢?广义表的实现应用到了一个很熟悉的算法--递归.来看看它的代码吧! #pragma once #include<iostream> #include<cassert> using namespace std; enum Type { HEAD,//头 VALUE, //值 SUB, //子表 }; struct GeneralizedNode { Type _type; General

递归实现广义表

广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列.由于在表的描述中可以嵌套表,允许表中有表,所以可以通过递归实现广义表. 具体实现如下: 头文件 #pragma once //实现广义表的结构 enum Type//枚举类型 { HEAD, VALUE, SUB, }; struct GeneralizedNode//广义表的结点 { Type _type;//类型 GeneralizedNode* _next;//值相同层的下一个节点 union//共用体/联合 { int 

广义表 (五)

5.1广义表-广义表的定义和基本运算 顾名思义,广义表是线性表的推广.也有人称其为列表(Lists,用复数形式以示与统称的表List 的区别). ⒈广义表的定义和性质 我们知道,线性表是由n 个数据元素组成的有限序列.其中每个组成元素被限定为单元素,有时这种限制需要拓宽.例如,中国举办的某体育项目国际邀请赛,参赛队清单可采用如下的表示形式: (俄罗斯,巴西,(国家,河北,四川),古巴,美国,(),日本) 在这个拓宽了的线性表中,韩国队应排在美国队的后面,但由于某种原因未参加,成为空表.国家队.河