广义表的递归实现

广义表的定义

广义表是非线性的结构,是线性表的一种扩展,是有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,//子表
};

//广义表结构
struct GeneralizedNode
{
public:
	//无参构造函数
	GeneralizedNode()
		:_type(HEAD)
		,_next(NULL)
	{}

	//有参的构造函数
	GeneralizedNode(Type type, char ch);

public:
	Type _type;
	GeneralizedNode* _next;

	//因为节点类型不可能既是数据节点又是子表结点,所以采用联合结构,
	//节省空间,便于管理。
	union
	{
		char _value;//数据结点
		GeneralizedNode* _subLink;//子表结点
	};
};

//有参的构造函数
GeneralizedNode::GeneralizedNode(Type type, char ch = 0)
	:_type(type)
	, _next(NULL)
{
	//数据节点则为数据初始化
	if (_type == VALUE)
	{
		_value = ch;
	}
	//子表结点的初始化
	else if (_type == SUB)
	{
		_subLink = NULL;
	}
}

广义表的定义:

注意:由于广义表的采用的是用递归实现。但构造函数,等成员函数不能够采用递归,而且在函数内部需要不断的传子表的head,对于成员函数直接使用成员变量_head,则无法递归下去。

//广义表类
class Generalized
{
public:
	//无参构造函数
	Generalized()
		:_head(new GeneralizedNode(HEAD))
	{}
	//有参构造函数
	Generalized(const char* str)
		:_head(NULL)
	{
		_head = CreateList(str);
	}

	//拷贝构造函数
	Generalized(const Generalized& g)
	{
		_head=_CopyList(g._head);
	}
	GeneralizedNode* _CopyList(GeneralizedNode* head);
	//赋值运算符的重载
	Generalized& operator=(Generalized g)
	{
		swap(_head, g._head);
		return *this;
	}

	//析构函数
	~Generalized()
	{
		_Delete(_head);
	}
	void _Delete(GeneralizedNode* head);
public:
	//打印广义表
	void Print()
	{
		_Print(_head);
	}

	//求广义表的大小
	size_t Size()
	{
		return _Size(_head);
	}

	//求广义表的深度
	size_t Depth()
	{
		return _Depth(_head);
	}

protected:
	//判断数据是否有效
	bool IsVaild(const char ch);
	//创建广义表
	GeneralizedNode* CreateList(const char* &str);
	void _Print(GeneralizedNode* head);
	size_t _Size(GeneralizedNode* head);
	size_t _Depth(GeneralizedNode* head);
private:
	GeneralizedNode* _head;
};

函数的实现

GeneralizedNode* Generalized::_CopyList(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;//需要拷贝的广义表的当前节点
	GeneralizedNode* _head = new GeneralizedNode();//拷贝广义表的头结点
	GeneralizedNode* index = _head;//拷贝广义表的当前节点
	while (cur)
	{
		//数据结点
		if (cur->_type == VALUE)
		{
			index->_next = new GeneralizedNode(VALUE, cur->_value);
			index = index->_next;
		}
		//子表结点,递归复制
		else if (cur->_type == SUB)
			{
				GeneralizedNode*SubNode = new GeneralizedNode(SUB);
				index->_next = SubNode;
				SubNode->_subLink= _CopyList(cur->_subLink);
				index = index->_next;
			}
		cur = cur->_next;
	}
	return _head;
}

void Generalized::_Delete(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	while (cur)
	{
		GeneralizedNode* del = cur;
		//递归删除子表
		if (cur->_type == SUB)
		{
			_Delete(cur->_subLink);
		}
		cur = cur->_next;
		delete del;
	}
}

//判断广义表的数据是否合法
bool Generalized::IsVaild(const char ch)
{
	if ((ch >= ‘0‘&&ch <= ‘9‘)
		|| (ch >= ‘a‘&&ch <= ‘z‘)
		|| (ch >= ‘A‘&&ch <= ‘Z‘))
	{
		return true;//合法
	}
	return false;//非法
}

GeneralizedNode* Generalized::CreateList(const char* &str)
{
	assert(str &&*str == ‘(‘);//断言防止传的广义表格式不对,或者为空
	str++;//跳过第一个(

	GeneralizedNode* head = new GeneralizedNode();//创建头结点
	GeneralizedNode* cur = head;
	while (*str)
	{
		if (IsVaild(*str))
		{

			cur->_next = new GeneralizedNode(VALUE, *str);
			cur = cur->_next;
			str++;
		}
		else if (*str == ‘(‘)//新的子表
		{
			GeneralizedNode* SubNode = new GeneralizedNode(SUB);
			SubNode->_subLink = CreateList(str);
			cur->_next = SubNode;
			cur = cur->_next;
		}
		else if (*str == ‘)‘)//广义表结束
		{
			str++;//返回之前需要给str++指向下一个
			return head;
		}
		else//空格或者逗号
		{
			str++;
		}
	}

	assert(false);
	return NULL;
}

void Generalized::_Print(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	if (cur == NULL)
	{
		cout << "()" << endl;
		return;
	}

	while (cur)
	{
		if (cur->_type == HEAD)
		{
			cout << "(";
		}
		else if (cur->_type == VALUE)
		{
			cout << cur->_value;
			//_value不是最后一个值
			if (cur->_next)
			{
				cout << ",";
			}
		}
		else if (cur->_type == SUB)
		{
			_Print(cur->_subLink);
			if (cur->_next)
			{
				cout << ",";
			}
		}
		cur = cur->_next;
	}
	//输出每个表最后一个(
	cout << ")";
}

size_t Generalized::_Size(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	size_t count = 0;
	while (cur)
	{
		if (cur->_type == VALUE)
		{
			count++;
		}
		//递归求取子表的大小
		if (cur->_type == SUB)
		{
			count = count + _Size(cur->_subLink);
		}
		cur = cur->_next;
	}
	return count;
}

size_t Generalized::_Depth(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	size_t depth = 1;//空表深度为1
	while (cur)
	{
		if (cur->_type == SUB)
		{
			size_t newDepth = _Depth(cur->_subLink);
			//如果子表的深度+1大于当前广义表的最大深度,则更新广义表的深度
			if (newDepth +1 > depth)
			{
				depth = newDepth + 1;
			}
		}
		cur = cur->_next;
	}
	return depth;
}

测试代码

#include"Generalized.h"

void TestGeneralized()
{
	Generalized l("(a,b,(c,d),(e,(f),h))");
	Generalized l1;
	l1 = l;
	l.Print();
	cout << endl;
	cout << "size:" << l.Size() << endl;
	cout << "depth:" << l.Depth() << endl;

	l1.Print();
	cout << endl;
	cout << "size:" << l1.Size() << endl;
	cout << "depth:" << l1.Depth() << endl;
}
int main()
{
	TestGeneralized();
	getchar();
	return 0;
}

测试结果

时间: 2024-10-11 01:06:26

广义表的递归实现的相关文章

广义表的递归数据结构的表示与实现--自己写数据结构

文件glist.h头文件如下 #ifndef _GLIST_H_ #define _GLIST_H_ typedef enum {ATOM,LIST}ElemTag; typedef struct _GList { ElemTag tag; union { char data; struct _GList *sublist; }val; struct _GList *next; }GList,*pGList; int glist_length(pGList pgl); int glist_dep

广义表的基本操作实现

广义表的四个特征:(1)广义线性表:(2)元素复合性:(3)元素递归性:(4)元素共享性 广义表的上述四个特征对于他的使用价值和应用效果起到了很大的作用.广义表的结构相当灵活,它可以兼容线性表.数组.树和有向图等各种常用的数据结构.当二维数组的每行或每列作为子表处理时,二维数组就是一个广义表:如果限制广义表中元素的共享和递归,广义表和树对应:如果限制广义表的递归并允许数据共享,则广义表和图对应. 广义表的基本操作有:(1)创建一个广义表(我以头尾链表作为存储结构):(2)取表头:(3)取表尾:(

广义表的有关知识点

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

数据结构4(数组和广义表)

第4章  数组和广义表 [例4-1]二维数组A的每一个元素是由6个字符组成的串,其行下标i=0,1,…,8,列下标j=1,2,…,10.若A以行为主序存储元素,A[8][5]的物理地址与当A按列为主序存储时的元素(  )的物理地址相同.设每个字符占一个字节. A.A[8][5]    B.A[3][10]    C.A[5][8]    D.A[0][9] //作图 解:  二维数A是一个9行10列的矩阵,即A[9][10].按行存储时,A[8][5]是第85个元素存储的元素.而按列存储时,第8

递归实现广义表

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

根据广义表建立对应二叉树(子女兄弟链表表示)并由二叉树输出对应广义表(子女兄弟链表表示)的C++非递归实现

根据输入的广义表建立子女右兄弟链的二叉树表示,该二叉树对应于广义表对应的普通树.先考虑更复杂的情形,如果广义表中存在共享表,则将其转换为带共享子树的二叉树表示,每一共享子树带有附加头节点,其左链指针指向共享子树,最后输出带共享子树的子女右兄弟链表示(广义表形式) C++代码: 1 #include "stdafx.h" 2 #include <iostream> 3 #include <stack> 4 #include <string> 5 #in

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

数据结构与算法系列研究四——数组和广义表

稀疏矩阵的十字链表实现和转置 一.数组和广义表的定义 数组的定义1:一个 N 维数组是受 N 组线性关系约束的线性表.           二维数组的逻辑结构可形式地描述为:           2_ARRAY(D,R)              其中 D={aij} | i=0,1,...,b1-1; j=0,1,...,b2-1;aij∈D0}              R={Row,Col}              Row={<aij,ai,j+1>|0<=i<=b1-1;

广义表的实现

/*--------------------------------------------------------------------- 广义表的存储结构 ---------------------------------------------------------------------*/ #include<stdio.h> #include<stdlib.h> typedef char ElemType;//元素类型是字符型 //广义表的存储结构 struct GN