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

广义表是我第一次用递归接触链式的数据结构,其结构如下:

HEAD->VAL->VAL->LINK(->HEAD.....)->VAL->......

    在这里,我们的头结点与link节点是不存储数据的,由此我们便可以定义出节点的数据结构:

typedef int DataType;
enum NodeType//枚举类型定义节点类型
{
	HEAD,
	VALUE,
	SUB,
};
struct GeneralizedNode
{
public:
	GeneralizedNode()
		:_next(NULL)
		, _link(NULL)
	{}
	NodeType _type;
	GeneralizedNode* _next;
	union//因为link与value是不可能同时存在的,故用共同体节省空间
	{
		GeneralizedNode* _link;
		DataType _value;
	};
};

因为广义表是链式的嵌套结构,所以我们必须用递归来进行遍历,这里面递归的方式有很多种,可以循环套递归,也可以递归套递归,也可以递归套循环,根据我们不同的需求,可以吧这三种方法都运用在合适的地方,这里,我简单的实现了,返回对象的层数,数据个数,以及一些常用的成员函数,其代码如下:

class Generalized
{
public:
	Generalized()
		:_head(NULL)
	{}
	Generalized(const char *str)//构造函数是用字符串来体现广义表如(1,2,(2,3))
	{                           //这样可以更好的体现出广义表的结构
		_head = _CreatList(str);
	}
	~Generalized()
	{
		_Destory(_head);
	}
	void Print()//控制台打印广义表,也是打印出字符串类型
	{
		_Print(_head);
	}
	Generalized(const Generalized &g)
	{
		_head = _Copy(g._head);
	}
	Generalized&operator = (Generalized g)
	{
		swap(_head, g._head);
		return *this;
	}
	size_t Depth()
	{
		return _Depth(_head);
	}
	size_t Size()
	{
		size_t size = 0;
		_Size(_head, size);
		return size;
	}
protected:
	size_t _Depth(GeneralizedNode* head)
	{
		size_t depth = 1;
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type == SUB)
			{
				size_t newdepth = _Depth(cur->_link) + 1;
				depth = depth < newdepth ? newdepth : depth;
			}
			cur = cur->_next;
		}
		return depth;
	}
	void _Size(GeneralizedNode* head, size_t &size)
	{
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type == VALUE)
				++size;
			else if (cur->_type == SUB)
				_Size(cur->_link, size);
			cur = cur->_next;
		}
	}
	GeneralizedNode* _Copy(GeneralizedNode *head)
	{
		GeneralizedNode* cur = head;
		GeneralizedNode* newHead = new GeneralizedNode;
		GeneralizedNode*tail = newHead;
		tail->_type = HEAD;
		while (cur)
		{
			if (cur->_type == SUB)
			{

				tail->_next = new GeneralizedNode;
				tail = tail->_next;
				tail->_type = SUB;
				tail->_link = _Copy(cur->_link);

			}
			else if (cur->_type == VALUE)
			{
				tail->_next = new GeneralizedNode;
				tail = tail->_next;
				tail->_type = VALUE;
				tail->_value = cur->_value;
			}
			cur = cur->_next;
		}
		return newHead;
	}
	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!=NULL&&
					cur->_next->_type == VALUE)
					cout << ",";
			}
			else
				_Print(cur->_link);
			cur = cur->_next;
		}
		cout << ")";
	}
	GeneralizedNode* _CreatList(const char* &str)
	{

		assert(‘(‘ == *str);
		GeneralizedNode* head = new GeneralizedNode;
		GeneralizedNode* cur = head;
		head->_type = HEAD;

		while (*++str)
		{
			if (IsValue(str))
			{
				cur->_next = new GeneralizedNode;
				cur = cur->_next;
				cur->_type = VALUE;
				cur->_value = *str;
				str++;
			}
			else if (‘)‘ == *str)
			{
				return head;
			}
			else if (‘(‘)
			{
				cur->_next = new GeneralizedNode;
				cur = cur->_next;
				cur->_type = SUB;
				cur->_link = _CreatList(str);
			}
			cur->_next = NULL;
			*str++;
		}
		return head;

	}
	bool IsValue(const char *str)//判断表内存储数据是否为所需数据类型
	{
		if (*str <= ‘9‘&&
			*str >= ‘0‘)
			return true;
		return false;
	}
	void _Destory(GeneralizedNode*head)
	{
		GeneralizedNode*cur = head;
		if (cur->_value == SUB)
			_Destory(cur->_link);
		else if (cur->_next != NULL)
			_Destory(cur->_next);
		delete cur;
	}
protected:
	GeneralizedNode* _head;
};

如有什么不足或疑问希望提出。

时间: 2024-10-09 16:36:40

【代码】C++实现广义表及其测试用例的相关文章

数据结构22:数组和广义表

本章主要介绍了数组和广义表的相关知识.数组章节,重点理解矩阵压缩存储的方式,在此基础上,学习矩阵的转置.乘法.和加法运算的实现:学习广义表时重点理解用递归的思想求广义表的深度和复制广义表. 本章内容: 1. 数据结构之多维数组 2. 矩阵压缩存储(十字链表.三元组顺序表.行逻辑 3. 矩阵转置算法及代码实现(三元组顺序表) 4. 矩阵乘法(行逻辑链接的顺序表)及代码实现 5. 矩阵加法(基于十字链表)及C语言代码实现 6. 广义表及M元多项式的C语言代码实现 7. 广义表的长度和深度 8. 广义

看数据结构写代码(52) 广义表的扩展线性链表存储表示

广义表 的另一种 存储结构是 扩展线性链表存储表示,这种 存储结构的 根 节点 必 存在,并且 根节点的 表尾 为空,将 根节点的 表尾 放 在 表头 的 表尾 指针上. 这样 从 表头 一直 就可以 遍历 所有 同级 节点. 具体j结构 如下: 例如 下面的 广义表 ,用 扩展线性链表 表示为: 而 头尾 存储表示,是 把 表头 和 表尾 都放在 根节点 的 指针上.其存储结构如下: 所以 其 实现 代码略有 不同,要 小心 处理 下面 上代码: // GList2.cpp : 定义控制台应用

看数据结构写代码(51) 广义表

广义表是一种非线性的数据结构.但如果广义表的每个元素都是原子,它就变成了线性表.广义表广泛地用于人工智能等领域的LISP语言. 广义表一般记作 LS = (a1, a2, ···, an), n是它的长度,ai可以是单个元素(原子),也可以是广义表(子表),当广义表非空时,称第一个元素a1为LS的表头,称其余元素组成的表为LS的表尾.注意:表头是元素(可以是原子,也可以是广表),表尾一定是广义表.E=(a, E)是一个递归的表.D=(( ),(e),(a,(b,c,d)))是多层次的广义表,长度

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;

33. 蛤蟆的数据结构笔记之三十三广义表实现二

33. 蛤蟆的数据结构笔记之三十三广义表实现二 本篇名言:" 希望是附丽于存在的,有存在,便有希望,有希望,便是光明.--鲁迅" 我们继续来看下广义表的其他代码实现.代码均来自网络,解释来自蛤蟆,均亲测可行. 欢迎转载,转载请标明出处: 1.  广义表实现二 1.1         main 创建两个链表的指针head和L. 输入一个字符串,调用GLCreate函数创建广义表.显示,获取头表,尾表,输出长度,深度,原子个数,复制列表,Merge列表,遍历,比较广义表操作. 如下图1:

javascript实现数据结构:广义表

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

第五章:1.数组和广义表 -- 数组

前言: 2.3.4章讨论的线性结构中的数据元素都是非结构的原子类型,元素的值是不再分解的.本章讨论的两种数据结构---数组和广义表可以看成是线性表在下述含以上的扩展:表中的数据元素本身也是一个数据结构. 其中.数组是一种比较熟知的数据类型,几乎所有程序语言都把数组类型设定为固有类型,前两节节以抽象数据类型的形式讨论数组的定义和实现,使读者加深对数组的理解. 目录: 1.数组的定义 2.数组的顺序表示和实现 3.矩阵的压缩存储 4.广义表的定义 5.广义表的存储结构 6.m元多项式的表示 7.广义

数据结构算法C语言实现(十九)--- 5.5&amp;5.6&amp;5.7广义表

一.简述 传说Lisp的基本数据结构就是广义表,广义表也是具有典型递归属性的数据结构,此外,由于建表要处理字符串,用C语言处理起来也是一脸懵逼.....最后自己还想写一个将广义表还原成字符串的函数,一是使其可视化,而是验证算法5.6.花了不少功夫才写出来(强烈建议自己动手写一写),最后是借助树形结构的角度才找到一个不错的解决办法.按照<数据结构编程实验>的分类,数据结构无非线性结构.树状结构.图结构,可以说树是特殊的图(图的最小生成树),线性表示特殊的树.....扯远了! 二.头文件 补充版字