广义表 的实现

广义表是非线性结构,其定义是递归的。

以下给出几种简单的广义表模型:

由上图我们可以看到,广义表的节点类型无非head、value、sub三种,这里设置枚举类型,利用枚举变量来记录每个节点的类型:

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

每个节点都有自己的类型以及next指针,除此之外,如果该节点是VALUE类型还要分配空间存储该节点的有效值;但是若该节点是SUB类型,就需定义一个指针指向子表的头。

这里我们可以用联合来解决这个问题。

(联合(或共同体)是一种不同数据类型成员之间共享存储空间的方法,并且联合体对象在同一时间只能存储一个成员值)

构造节点

struct GeneralizedNode
{
	Type _type;       //  1.类型
	GeneralizedNode* _next;  //2.指向同层的下一个节点
	union
	{
		char _value;    //  3.有效值
		GeneralizedNode* _subLink;     // 3.指向子表的指针
	};

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

广义表的定义及基本操作

class Generalized
{
public:
	//无参的构造函数,建立空的广义表
	Generalized();
	//建造广义表,有参数的构造函数
	Generalized(const char* str);
	//打印广义表
	void Print();
	//获取值节点的个数
	size_t Amount();
	//获取广义表的深度
	size_t Depth();
	//拷贝构造
	Generalized(const Generalized& g);
	////赋值运算符的重载
	Generalized& operator=(const Generalized& g);
	////析构函数
	~Generalized();

protected:
	void _Print(GeneralizedNode* head);
	GeneralizedNode* _CreatList(const char*& str);
	size_t _Amount(GeneralizedNode* head);
	GeneralizedNode* _Copy(GeneralizedNode* head);
	void _Destory(GeneralizedNode* head);
protected:
	GeneralizedNode* _head;   //记录广义表头指针
};

初始化建立广义表进行循环递归。遍历字符串时遇到字符就建立值节点,遇到‘(‘就进行递归并建立子表;遇到‘)‘就结束当前子表的建立,并返回当前子表的头指针。

GeneralizedNode* _CreatList(const char*& str)
	{
		assert(*str == ‘(‘);
		GeneralizedNode* head = new GeneralizedNode(HEAD,‘0‘);
		GeneralizedNode* cur = head;
		str++;
		while (str != ‘\0‘)
		{
			if ((*str >= ‘0‘&&*str <= ‘9‘) || (*str >= ‘a‘&&*str <= ‘z‘) || (*str >= ‘A‘&&*str <= ‘Z‘))
			{
				cur->_next = new GeneralizedNode(VALUE, *str);
				cur = cur->_next;
			}
			else if (*str == ‘(‘)
			{
				cur->_next = new GeneralizedNode(SUB);
				cur = cur->_next;
				cur->_subLink = _CreatList(str);
			}
			else if (*str == ‘)‘)
			{
				return head;
			}
			str++;
		}
		return head;
	}

打印广义表:当节点的类型为SUB时进行递归,最后不要忘了每打印完一层要打印一个后括号。

void _Print(GeneralizedNode* head)
	{
		if (head == NULL)
		{
			cout << "Generalized table is NULL" << endl;
			return;
		}
		GeneralizedNode* cur = head;
		while (cur)
		{
			if (cur->_type == HEAD)
			{
				cout << ‘(‘;
			}
			else if (cur->_type == VALUE)
			{
				cout << cur->_value;
				if (cur->_next)
				{
					cout << ‘,‘;
				}
			}
			else if (cur->_type == SUB)
			{
				_Print(cur->_subLink);
				if (cur->_next)
				{
					cout << ‘,‘;
				}
			}
			cur = cur->_next;
		}
		cout << ‘)‘;
	}

获取值节点的个数:设置count变量,遇到值节点就加1,遇到SUB节点进行递归并将返回值加给count

size_t _Amount(GeneralizedNode* head)
	{
		GeneralizedNode* begin = head;
		size_t count = 0;
		while (begin)
		{
			if (begin->_type == VALUE)
			{
				count++;
			}
			if (begin->_type == SUB)
			{
				count += _Amount(begin->_subLink);
			}
			begin = begin->_next;
		}
		return count;
	}

广义表的深度:设置变量dp和max分别用来记录当前子表即当前SUB节点指向的子表深度,以及本层所有的SUB节点中深度最大的子表的数目。

size_t _Depth(GeneralizedNode* head)
	{
		if (_head == NULL)
		{
			return 0;
		}
		size_t dp=0;
		GeneralizedNode* cur = head;
		size_t max = 0;
		while (cur)
		{
			if (cur->_type == SUB)
			{
				dp=_Depth(cur->_subLink);
				if (max < dp)
				{
					max = dp;
				}
			}
			cur = cur->_next;
		}
		return max+1;
	}

销毁广义表:依次遍历节点,遇到子表递归,将子表的节点delete完成后,再回到当前层继续遍历。

void _Destory(GeneralizedNode* head)
	{
		if (head == NULL)
		{
			return;
		}
		while (head)
		{
			GeneralizedNode* begin = head->_next;
			if (head->_type == SUB)
			{
				_Destory(head->_subLink);
			}
			delete head;
			head = begin;
		}
	}

广义表的拷贝构造及赋值运算符重载与构造函数的递归方式类似,这里就不再阐述冗余信息。

时间: 2024-10-01 05:16:57

广义表 的实现的相关文章

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

数据结构实践项目——数组和广义表

本文针对 [数据结构基础系列网络课程(5):数组和广义表] 1. 数组的基本概念与存储结构 2. 特殊矩阵的压缩存储 3. 稀疏矩阵的三元组表示 4. 稀疏矩阵的十字链表表示 5. 广义表 6. 广义表的存储结构及基本运算的实现 [项目1 - 猴子选大王(数组版)] 一群猴子,编号是1,2,3 -m,这群猴子(m个)按照1-m的顺序围坐一圈.从第1只开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,最后一只出圈的猴子为大王.输入m和n,输出猴子离开圈子的顺序,从中也可以看出最后为大王是几号

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

稀疏矩阵的十字链表实现和转置 一.数组和广义表的定义 数组的定义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

广义表的实现(法二)

#include<iostream> #include<string> using namespace std; enum elemTag {ATOM,LIST}; class GList; class GLnode { private: elemTag Tag; //标志是原子还是子表 0:原子 1:子表 union { char data; //原子结点值域 struct //表结点指针域 { GLnode *hp; GLnode *tp; }ptr; }; friend cl

广义表

其中包括广义表的创建.输出.拷贝构造.赋值运算符重载.析构.有效数据个数以及广义表深度 #pragma once #include<iostream> #include<assert.h> #include<ctype.h> using namespace std; enum Type {  HEAD, VALUE, SUB };//头结点.值.子表 struct GeneralizedNode {  Type _type;  //广义表结点类型  Generalize

数据结构之广义表

#include<stdio.h> //广义表的头尾链表存储结构 typedef int AtomType; typedef enum NodeType{ATOM,LIST}ElemTag;//ATOM表示原子结点,LIST表示表节点 typedef struct GLNode{ ElemTag tag; union{ AtomType atom; struct List{ struct GLNode* hp,*tp; } htp; }atom_htp; }GLNode,*GList; //求

数据结构——广义表

定义 Python中的list就是一种广义表,使用起来非常方便.广义表的特点就是能够存储不同类型的元素,也支持嵌套使用,即表中还有表.关于广义表的定义还有几本操作归纳如下: ADT Linear List: 元素组成: 能存储不同元素类型的表结构叫做广义表,支持嵌套操作. 基本操作: InitGList() 创建一个空表 DestoryGList() 销毁一个表 GListLength()  获取表的长度 GListDepth()  获取表的深度 PrintList() 遍历一次表 Insert

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

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

数据结构之---C语言实现广义表头尾链表存储表示

//广义表的头尾链表存储表示 //杨鑫 #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> #define MAXSTRLEN 40 ) typedef char SString[MAXSTRLEN+1]; typedef char AtomType; // 定义原子类型为字符型 typedef enum{ ATOM, LIST // ATOM==0:原