c++数据结构之广义表

原创 2016年05月31日 09:07:52

最近学习了广义表,我们知道广义表也是一种线性表,而顾名思义广义表就是不止一个表,下面来举个栗子:

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为例来看一下它的结构图:

wKiom1cXaDXAgQb6AAAlQ9FgaVQ092.png

spacer.gif

(图画得有点丑,不要吐槽我)

每当遇到一个前括号,就要创建一个子表,直到遇见收括号。


那么如何创建一个广义表呢,在创建节点结构体的时候,我们要考虑每个节点的类型,有可能是头结

点,也有可能是子表节点,也有可能是普通的值节点,所以在构造节点的时候就要定义一个三元体,由

于是表里有表,我们可以用递归的方法来解决广义表的问题,每个子表都可以递归为一个子问题,就可

以很轻松的解决掉这个问题了。


下面是具体实现的代码:


先构造一个三元结构体:

enum Type
{
	HEAD,
	VALUE,
	SUB,
};
template<class T>
struct GeneralizedNode
{
	Type _type;
	GeneralizedNode<T>* _next;

	union
	{
		char _value;
		GeneralizedNode<T>* _sublink;   //子表的头结点
	};
public:
	GeneralizedNode(Type type = HEAD,char value = '\0')
		:_type(type)
		,_next(NULL)
	{
			if (type == VALUE)
			{
				_value = value;
			}
			else if (type == SUB)
			{
				_sublink = NULL;
			}
		}
};

下面来构造一个广义表类

template<class T>
class GeneralizedList
{
public:
	GeneralizedList()
		:_head(new GeneralizedNode<T>(HEAD))
	{}
	GeneralizedList(const char* str)
	{
		_head=_CreateList(str);
	}
	GeneralizedList(const GeneralizedList& g)    //拷贝构造
	{
		_head = Copy(g._head;)
	}
	size_t Size()
	{
		return size(_head);
	}
	size_t depth()
	{
		return Depth(_head);
	}
	
	void print()
	{
		Print(_head);
	}
protected:
	GeneralizedNode<T>* _CreateList(const char*& str)
	{
		assert(str && *str == '(');
			++str;

		GeneralizedNode<T>* Head = new GeneralizedNode<T>(HEAD,NULL);
		GeneralizedNode<T>* cur = Head;

		while (*str)
		{
			if (_IsValue(*str))
			{
				cur->_next = new GeneralizedNode<T>(VALUE,*str);

				cur = cur->_next;
				str++;
			}
			else if (*str == '(')
			{
				GeneralizedNode<T>* newNode= new GeneralizedNode<T>(SUB);        //将一个子表结点加入到链表中
				cur->_next = newNode;
				cur = cur->_next;
				cur->_sublink = _CreateList(str);

				str++;//递归创建一个子表结点
			}
			else if (*str == ')')               //表示一个表已经结束
			{
				str++;
				return Head;
			}
			else
			{
				str++;     //不需要处理的情况
			}
			
		}
		assert(false);
		return Head;
	}


	size_t Depth(GeneralizedNode<T>* head)
	{
		GeneralizedNode<T>* cur = head;
		size_t depth = 1;

		while (cur)
		{
			if (cur->_type == SUB)
			{
				size_t subdepth = Depth(cur->_sublink);
			
			if (subdepth+1 > depth)
			{
				depth=subdepth;//保存较大的深度
			}
			}
			cur = cur->_next;
		}
		
		return depth;
	}


	size_t size(GeneralizedNode<T>* head)
	{
		GeneralizedNode<T>* cur = head;

		size_t count = 0;
		while (cur)
		{
			if (cur->_type != SUB)
			{
				count++;
			}
			else
			{
				count += size(cur->_sublink);
			}
			cur = cur->_next;
		}
		return count;
	}

	void Print(GeneralizedNode<T>* head)
	{
		GeneralizedNode<T>* cur = head;
		while (cur)
		{
             if (cur->_type == HEAD)
			{
				cout << '(';
			}
			else if (cur->_type == VALUE)
			{
				cout << cur->_value ;
				if (cur->_next != NULL)
				{
					cout << ',' ;
				}
			}
			
			else if (cur->_type == SUB)
			{
				Print(cur->_sublink);
				if (cur->_next != NULL)
				{
					cout << ',';
				}
			}
			cur = cur->_next;
		}
		cout << ')';
		
	}
	
	
	bool _IsValue(char ch)   //检查是否为合法值
	{
		if ((ch >= '0'&&ch<='9') || (ch>='a'&&ch<='z') || (ch>='A'&&ch <= 'Z'))
		{
			return true;
		}
		return false;
	}
protected:
	GeneralizedNode<T>* _head;
};

下面给出测试代码:

#include"Generalized.h"
void Test()
{
	char* ch = "(a,b,c,(1,2),c)";
	GeneralizedList<char> gl1(ch);
	gl1.print();
	cout << endl;
	cout << "广义表深度为:" << gl1.depth() << endl;
	cout << "广义表大小为:" << gl1.Size() << endl;
}

int main()
{
	Test();
	getchar();
	return 0;
}

运行结果:

wKiom1cXayDxqM9wAAAFVrKt1gA365.png


以上就是C++实现广义表的方法啦,里面也许还存在着一些问题,希望大家能够指正出来,共同促进学习。

本文出自 “福大馨” 博客,转载请与作者联系!

版权声明:本文为博主原创文章,未经博主允许不得转载。

C++实现广义表

定义: 广义表是n(n≥0)个元素a1,a2,…,ai,…,an的有限序列。   其中:   ①ai--或者是原子或者是一个广义表。   ②广义表通常记作:   Ls=( a1,a2,…,a...

广义表的实现(c++实现)

本文要点: 1.广义表的存储结构 2.广义表的简单实现,包括:构造、拷贝构造、赋值运算符重载、广义表的大小Size、深度Depth以及输出函数...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

数据结构学习笔记之广义表的相关知识点

广义表(Lists,又称列表)是一种非线性的数据结构,是线性表的一种推广,广泛的应用于人工智能等领域的表处理语言LISP语言中,因此,掌握对广义表的基础的CRUD操作很是重要...

5.5 广义表的存储结构

/* c5-5.h 广义表的头尾链表存储表示 */  typedef enum{ATOM,LIST}ElemTag; /* ATOM==0:原子,LIST==1:子表 */  typedef st...
  • sjmping
  • sjmping
  • 2012年11月18日 15:49
  • 6080

数据结构学习-数组和广义表

问题描述:假设n*n的稀疏矩阵A采用三元组表示,设计一个程序实现如下功能: 1.生成如下2个稀疏矩阵的三元组a和b; ⎡ ⎣ ⎢ ⎢ ⎢ 1000 0100 3011 0001 ⎤ ...
  • shope9
  • shope9
  • 2016年05月31日 17:20
  • 993

数据结构_数组与广义表_广义表的建立、遍历、复制、求深度

由一个存储着广义表信息的字符串建立一个广义表,并对其进行复制,求深度。 递归真是奇妙无穷啊,有些看似很复杂的东西只要找到规律就能进行递归求解。让我不得不对那些发现规律利用规律创造新事物的人肃然起...

【数据结构】数组和广义表

第五章  数组和广义表 5.1 数组的类型定义 ADT Array {   数据对象:       D={aj1,j2, ...,,ji,jn| ji =0,...,bi -1...
  • zscfa
  • zscfa
  • 2016年10月04日 21:19
  • 1190

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

数据结构 C++ 二叉树 广义表

  • 2008年12月18日 20:37
  • 1.65MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:c++数据结构之广义表
举报原因:
原因补充:

(最多只允许输入30个字)