递归实现广义表

广义表是非线性的结构,是线性表的一种扩展,是有n个元素组成有限序列。由于在表的描述中可以嵌套表,允许表中有表,所以可以通过递归实现广义表。

具体实现如下:

头文件

#pragma once
//实现广义表的结构
enum Type//枚举类型
{
	HEAD,
	VALUE,
	SUB,
};

struct GeneralizedNode//广义表的结点
{
	Type _type;//类型
	GeneralizedNode* _next;//值相同层的下一个节点
	union//共用体/联合
	{
		int _value;//值节点
		GeneralizedNode* _SubLink;//指向字表的指针
	};
	GeneralizedNode();
	GeneralizedNode(Type type, int value); //全缺省构造函数
};

class Generalized
{
public:
	Generalized();
	Generalized(const char* str);//构造
	Generalized(const Generalized& g);//拷贝构造
	Generalized& operator=(const Generalized& g);
	~Generalized();
	void Print();
	size_t Size();
	size_t Depth();
protected:
	GeneralizedNode* _CreatList(const char*& str);
	GeneralizedNode* _Copy(GeneralizedNode* head);
	bool _isValue(char ch);//判断是否为字母或数字
	void _Distory(GeneralizedNode* head);
	void _Print(GeneralizedNode* head);
	size_t _Size(GeneralizedNode* head);
	size_t _Depth(GeneralizedNode* head);
protected:
	GeneralizedNode* _head;
};

各函数的具体实现

#include<iostream>
#include<assert.h>
#include<string>
using namespace std;
#include"Generalized.h"

GeneralizedNode::GeneralizedNode()
:_next(NULL)
{}
GeneralizedNode::GeneralizedNode(Type type, int value)
: _type(type)
, _next(NULL)
{
	if (_type == VALUE)
	{
		_value = value;
	}
	if (_type == SUB)
	{
		_SubLink = NULL;
	}
}
Generalized::Generalized()
:_head(NULL)
{}
Generalized::Generalized(const char* str)//构造函数
: _head(NULL)
{
	_head = _CreatList(str);
}
GeneralizedNode* Generalized::_CreatList(const char*& str)
{//广义表:(a, (b, c))
	assert(‘(‘ == *str); 
	str++;
	GeneralizedNode* head = new GeneralizedNode(HEAD, 0);//建立表的头结点
	GeneralizedNode* cur = head;
	while (str)
	{
		if (_isValue(*str))//*str为字母或数字
		{
			cur->_next = new GeneralizedNode(VALUE, *str);//建立value结点
			cur = cur->_next;
			str++;
		}
		else if (*str == ‘(‘)//如果为(,则出现字表,进行递归调用
		{
			GeneralizedNode* subNode = new GeneralizedNode(SUB, 0);//建立子表结点
			cur->_next = subNode;
			cur = cur->_next;
			subNode->_SubLink = _CreatList(str);//_SubLink指向子表构造子表
		}
		else if (*str == ‘)‘)//表示表的结束(包括子表),返回表的头结点
		{
			str++;
			return head;
		}
		else
		{
			str++;
		}
	}
	assert(false);
	return head;
}
bool Generalized::_isValue(char ch)//判断是否为字母或数字
{
	if (ch >= ‘0‘ && ch <= ‘9‘ || ch >= ‘a‘ && ch <= ‘z‘ || ch >= ‘A‘ && ch <= ‘Z‘)
	{
		return true;
	}
	return false;
}
Generalized::Generalized(const Generalized& g)//拷贝构造函数
{
	_head = _Copy(g._head);
}
GeneralizedNode* Generalized::_Copy(GeneralizedNode* head)
{
	GeneralizedNode* newhead = new GeneralizedNode(HEAD, 0);
	GeneralizedNode* cur = head;
	GeneralizedNode* newcur = newhead;
	while (cur)
	{
		if (cur->_type == VALUE)//cur._type为VALUE或SUB时建立结点,newcur才存在指向下一个结点
		{
			newcur->_next = new GeneralizedNode(VALUE, cur->_value);
			newcur = newcur->_next;
		}
		if (cur->_type == SUB)
		{
		    newcur->_next= new GeneralizedNode(SUB, 0);
			newcur = newcur->_next;
			newcur->_SubLink = _Copy(cur->_SubLink);//递归调用_Copy进行复制
		}
		cur = cur->_next;
	}
	return newhead;
}
Generalized& Generalized::operator=(const Generalized& g)//传统写法
{
	if (this != &g)
	{
		GeneralizedNode* tmp = _Copy(g._head);
		_Distory(_head);
		_head = tmp;
	}
	return *this;
}
Generalized::~Generalized()
{
	_Distory(_head);
}
void Generalized::_Distory(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	while (cur)
	{
		GeneralizedNode* del = cur;
		if (cur->_type == SUB)
		{
			_Distory(cur->_SubLink);//释放cur结点的字表
		}
		cur = cur->_next;
		delete del;
	}
}
void Generalized::Print()
{
	_Print(_head);
	cout << endl;
}
void Generalized::_Print(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	while (cur)
	{
		if (cur->_type == HEAD)
		{
			cout << "(";
		}
		if (cur->_type == VALUE)
		{
			cout << (char)cur->_value;//强转为char类型
			if (cur->_next)//如果cur->_next不为空打印“,”
				cout << ",";
		}
		if (cur->_type == SUB)
		{
			_Print(cur->_SubLink);
			if (cur->_next)
				cout << ",";
		}
		cur = cur->_next;
	}
	cout << ")";
}
size_t Generalized::Size()
{
	return _Size(_head);
}
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 += _Size(cur->_SubLink);
		}
		cur = cur->_next;
	}
	return count;
}
size_t Generalized::Depth()
{
	return _Depth(_head);
}
size_t Generalized::_Depth(GeneralizedNode* head)
{
	GeneralizedNode* cur = head;
	size_t depth = 1;
	while (cur)
	{
		if (cur->_type == SUB)
		{
			size_t cdepth = _Depth(cur->_SubLink);
			if (cdepth + 1 > depth)//比较子表深度,保存较大的
			{
				depth = cdepth + 1;
			}
		}
		cur = cur->_next;
	}
	return depth;
}

测试用例如下:

void Test()
{
	//Generalized g1("(a)");
	//Generalized g2("(a,b)");
	Generalized g3("(a,(a,b))");
	Generalized g4("(a,(a,(b),c),d)");
	Generalized g5 = g4;
	g5 = g3;
	//g1.Print();
	//g2.Print();
	g3.Print();
	g4.Print();
	g5.Print();
	cout << "g3.Size():" << g3.Size() << endl;
	cout << "g4.Size():" << g4.Size() << endl;
	cout << "g3.Depth():" << g3.Depth() << endl;
	cout << "g4.Depth():" << g4.Depth() << endl;
}
时间: 2024-08-14 20:29:06

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

javascript实现数据结构:广义表

原文:javascript实现数据结构:广义表  广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an) LS是广义表的名称,n是它的长度,ai可以是单个元素,也可以是广义表,分别称为广义表LS的原子和子表.习惯上,用大写字母表示广义表的名称,小写字母表示原子.当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2, a3, ..., an)是LS的表尾. 下面列举一些广义表的例

数据结构之用C++实现广义表

广义表,相对于链表较复杂,相对于树又较简单....用来过渡顺序表和树是非常好的选择. 废话不多说,一言不合就贴代码. /* *文件说明:广义表相关声明及定义 *作者:高小调 *日期:2016-12-12 *集成开发环境:Microsoft Visual Studio 2010 */ #ifndef __GENERALLIST_H__ #define __GENERALLIST_H__ #include<assert.h> enum Type{ HEAD, SUB, VALUE }; struc

广义表(非线性结构)

广义表 广义表是一种非线性的数据结构,是一种较为简单的数据结构,是线性表的扩展,是一个由n个元素组成的序列.实现广义表主要是利用递归,将其分为子问题来进行解决.下面是一些常见类型的广义表: 1)A = ():          常称为"空表" 2)B = (a,b):          一般的广义表 3)C = (a, b, (c, d))         具有子表的广义表 4)D = (a, b, (c,(d)))        子表中有表的广义表 5)E = ((),())    

[转]广义表

(C版) #include <stdio.h>#include <malloc.h>#define OK 1#define ERROR -1#define status inttypedef struct gnode{ int tag; union {  char atom;  struct gnode *sublist; } val; struct gnode *link;} *Gnode;Gnode creatglist(char *s){//创建广义表 Gnode h; ch

广义表的基本操作实现

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

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

文件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

广义表的递归实现

广义表的定义 广义表是非线性的结构,是线性表的一种扩展,是有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++非递归实现

根据输入的广义表建立子女右兄弟链的二叉树表示,该二叉树对应于广义表对应的普通树.先考虑更复杂的情形,如果广义表中存在共享表,则将其转换为带共享子树的二叉树表示,每一共享子树带有附加头节点,其左链指针指向共享子树,最后输出带共享子树的子女右兄弟链表示(广义表形式) 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