数据结构::关于广义表的那些事~~

本文详细探讨了广义表的概念,包括其定义、表示方式、基本性质以及实现方法。广义表是由原子或广义表构成的有限序列,用大写字母表示,递归定义其结构,包含表头和表尾。广义表在数据结构中具有重要意义,是理解递归数据结构的关键。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、广义表

1.1广义表的定义

1.2广义表的表示

1.3广义表的性质

1.4广义表的实现

【广义表的定义】:是由N个元素组成的有限序列,它的定义是递归的,因为它允许表中有表。
【广义表的表示】:

广义表是n(n≥0)个元素a1,a2,…,ai,…,an的有限序列。

其中:

①ai--或者是原子或者是一个广义表。

②广义表通常记作:

Ls=( a1,a2,…,ai,…,an)。

③Ls是广义表的名字,n为它的长度

④若ai是广义表,则称它为Ls的子表

注意:

①广义表通常用圆括号括起来,用逗号分隔其中的元素。

②为了区分原子和广义表,书写时用大写字母表示广义表,用小写字母表示原子

③若广义表Ls非空(n≥1),则al是LS的表头,其余元素组成的表(a1,a2,…,an)称为Ls的表尾。

④广义表是递归定义的

举例如下:



【广义表的性质】:它是非线性结构的,是线性表的一种扩展
【广义表的实现】:
我们以下图为例进行说明和实现:

我们进行分析:
1)在我们实现的广义表中定义的时候都带了头结点
2)我们不难发现,每一个节点都会有自己的类型和指向下一个节点的指针,类型无非就是这三种:带头结点,数值,和有子表的,因此我们可以这样定义
enum Type
{
	HEAD,
	VALUE,
	SUB
};
struct GeneralListNode
{
	GeneralListNode(const Type& type,char value = 0)
		:_type(type)
		,_next(NULL)
		,_sublink(NULL)
	{
		_value = value;   //注意这块直接赋值
	}
	Type _type;
	GeneralListNode* _next;
	union
	{
		char _value;
		GeneralListNode* _sublink;
	};
};
3)那么接下来我们就来实现广义表的其它接口
class GeneralList
{
public:
	typedef GeneralListNode Node;
public:
	//构造函数
	GeneralList()
		:_head(NULL)
	{}
	GeneralList(const char* str)
		:_head(NULL)
	{
		_head = Creat(str);	
	}
	Node* Creat(const char*&str)   //注意传引用
	{
		assert(str&&*str == '(');
		Node* head = new Node(HEAD);//先定义一个只有头节点的
		Node* cur = head;
		str++;
		//接下来分情况:有值得或者是有子表的,或者其他
		while(*str)
		{
			if((*str >= '0' && *str<='9')||
				(*str>='a' && *str<='z')||
				(*str>='A' && *str<='Z'))
			{
				Node* ret = new Node(VALUE,*str);
				cur->_next = ret;
				cur = cur->_next;
				str++;
			}
			else if(*str == '(')
			{
				Node* ret = new Node(SUB);
				cur->_next = ret;
				//str++;
				ret->_sublink = Creat(str);
				cur = cur->_next;
			}
			else if(*str == ')')  //已经到广义表的最后了
			{
				str++;
				return head;
			}
			else
			{
				++str;
			}
		}
		return head;
	}
	//拷贝构造函数
	GeneralList(const GeneralList& g)
	{
		_head = Copy(g._head);
	}
	Node* Copy(Node* head)
	{
		assert(head&&head->_type==HEAD);
		Node* cur = head;  //原来的
		Node* tail = new Node(HEAD);  //指向子表
		Node* newhead = tail;
		while(cur)
		{
			if(cur->_type == VALUE)
			{
				Node* ret = new Node(cur->_type,cur->_value);
				tail->_next = ret;
				tail = tail->_next;
				cur = cur->_next;
			}
			else if(cur->_type == SUB)
			{
				Node* ret = new Node(cur->_type);
				tail->_next = ret;
				tail = tail->_next;
				tail->_sublink = Copy(cur->_sublink);
				cur = cur->_next;
			}
			else
				cur = cur->_next;
		}
		return newhead;
	}
	//赋值运算符重载
	GeneralList& operator=(const GeneralList& g)
	{
		//普通的传统写法
		if(this != &g)
		{
			Node* temp = Copy(g._head);
			if(_head!=NULL)
				Destory(_head);
			_head = temp;
		}
		return *this;
		//现在的简洁写法:
		/*:写法一:
		Node* Assign temp(g);
		std::swap(_head,temp._head);
		return *this;

		写法二:
		Node* Assign(GeneralList g)
		{
			swap(_head,g._head);
			return *this;
		}
		写法三:
		Node* Assign(const GeneralList& g)
		{
			Assign temp(g._head);
			swap(_head,temp._head);
			return *this;
		}
		*/
	
	}	
	//析构函数
	~GeneralList()
	{
		if(_head)
		{
			Destory(_head);
		}
		_head = NULL;
	}
	void Destory(Node* head)
	{
		assert(head&&head->_type==HEAD);
		Node* cur = head;
		while(cur)
		{
			if(cur->_type == SUB)
			{
				Destory(cur->_sublink);
			}
			Node* del = cur;
			cur = cur->_next;
			delete del;
		}
	}
	//求广义表的元素的个数
	size_t Size()
	{
		return _Size(_head);
	}
	size_t _Size(Node* head)
	{
		assert(head&&head->_type==HEAD);
		size_t count = 0;
		Node* cur = head;
		while(cur)
		{
			if(cur->_type == VALUE)
			{
				count++;
			}
			if(cur->_type == SUB)
			{
				count += _Size(cur->_sublink);
			}
			cur = cur->_next;
		}
		return count;
	}
	//求广义表的深度
	size_t Depth()
	{
		return _Depth(_head);
	}
	size_t _Depth(Node* head)
	{
		assert(head&&head->_type==HEAD);
		size_t maxSize = 1;
		size_t depth = 1;
		Node* cur = head;
		while(cur)
		{
			if(cur->_type == SUB)
			{
				if(depth+1 > maxSize)
				{
					maxSize = depth+1;
				}
				depth = _Depth(cur->_sublink);
			}
			cur = cur->_next;
		}
		return maxSize;
	}
	//打印函数
	void Print()
	{
		_Print(_head);
		cout<<endl;
	}
	//(a,b,(c,d))
	void _Print(Node* head)
	{
		assert(head&&head->_type==HEAD);
		Node* cur = head;
		cout<<'(';
		while(cur)	
		{
			if(cur->_type == HEAD)
			{
				cur = cur->_next;
			}
			else if(cur->_type == VALUE)
			{
				cout<<cur->_value;
				if(cur->_next)
				{
					cout<<',';
					cur = cur->_next;
				}
				else
				{
					return ;
				}
			}
			else if(cur->_type == SUB)
			{
				_Print(cur->_sublink);
				cout<<')';
				if(cur->_next)
				{
					cout<<',';
					cur = cur->_next;
				}
				else
				{
					break;
				}
			}
		}
			cout<<')';
			
	}
protected:
	Node* _head;
};
4)注意我们在实现广义表的时候有的广义表是有子表的嵌套的,因此实现的时候,我们会采取递归的方式,一般在类里实现成员函数的递归的时候我们不直接进行递归的实现,而是将它封装成一个函数。但是读者看我上面实现的函数,举个例子:看构造函数,我没有直接在定义构造函数的函数体里实现,而是封装了一个Creat函数。
最后我把完整的代码附上:吐舌头
#include<iostream>
#include<assert.h>
using namespace std;
//广义表的类型:三种:
enum Type
{
	HEAD,
	VALUE,
	SUB
};
struct GeneralListNode
{
	GeneralListNode(const Type& type,char value = 0)
		:_type(type)
		,_next(NULL)
		,_sublink(NULL)
	{
		_value = value;   //注意这块直接赋值
	}
	Type _type;
	GeneralListNode* _next;
	union
	{
		char _value;
		GeneralListNode* _sublink;
	};
};
class GeneralList
{
public:
	typedef GeneralListNode Node;
public:
	//构造函数
	GeneralList()
		:_head(NULL)
	{}
	GeneralList(const char* str)
		:_head(NULL)
	{
		_head = Creat(str);	
	}
	Node* Creat(const char*&str)   //注意传引用
	{
		assert(str&&*str == '(');
		Node* head = new Node(HEAD);//先定义一个只有头节点的
		Node* cur = head;
		str++;
		//接下来分情况:有值得或者是有子表的,或者其他
		while(*str)
		{
			if((*str >= '0' && *str<='9')||
				(*str>='a' && *str<='z')||
				(*str>='A' && *str<='Z'))
			{
				Node* ret = new Node(VALUE,*str);
				cur->_next = ret;
				cur = cur->_next;
				str++;
			}
			else if(*str == '(')
			{
				Node* ret = new Node(SUB);
				cur->_next = ret;
				//str++;
				ret->_sublink = Creat(str);
				cur = cur->_next;
			}
			else if(*str == ')')  //已经到广义表的最后了
			{
				str++;
				return head;
			}
			else
			{
				++str;
			}
		}
		return head;
	}
	//拷贝构造函数
	GeneralList(const GeneralList& g)
	{
		_head = Copy(g._head);
	}
	Node* Copy(Node* head)
	{
		assert(head&&head->_type==HEAD);
		Node* cur = head;  //原来的
		Node* tail = new Node(HEAD);  //指向子表
		Node* newhead = tail;
		while(cur)
		{
			if(cur->_type == VALUE)
			{
				Node* ret = new Node(cur->_type,cur->_value);
				tail->_next = ret;
				tail = tail->_next;
				cur = cur->_next;
			}
			else if(cur->_type == SUB)
			{
				Node* ret = new Node(cur->_type);
				tail->_next = ret;
				tail = tail->_next;
				tail->_sublink = Copy(cur->_sublink);
				cur = cur->_next;
			}
			else
				cur = cur->_next;
		}
		return newhead;
	}
	//赋值运算符重载
	GeneralList& operator=(const GeneralList& g)
	{
		//普通的传统写法
		if(this != &g)
		{
			Node* temp = Copy(g._head);
			if(_head!=NULL)
				Destory(_head);
			_head = temp;
		}
		return *this;
		//现在的简洁写法:
		/*:写法一:
		Node* Assign temp(g);
		std::swap(_head,temp._head);
		return *this;

		写法二:
		Node* Assign(GeneralList g)
		{
			swap(_head,g._head);
			return *this;
		}
		写法三:
		Node* Assign(const GeneralList& g)
		{
			Assign temp(g._head);
			swap(_head,temp._head);
			return *this;
		}
		*/
	
	}	
	//析构函数
	~GeneralList()
	{
		if(_head)
		{
			Destory(_head);
		}
		_head = NULL;
	}
	void Destory(Node* head)
	{
		assert(head&&head->_type==HEAD);
		Node* cur = head;
		while(cur)
		{
			if(cur->_type == SUB)
			{
				Destory(cur->_sublink);
			}
			Node* del = cur;
			cur = cur->_next;
			delete del;
		}
	}
	//求广义表的元素的个数
	size_t Size()
	{
		return _Size(_head);
	}
	size_t _Size(Node* head)
	{
		assert(head&&head->_type==HEAD);
		size_t count = 0;
		Node* cur = head;
		while(cur)
		{
			if(cur->_type == VALUE)
			{
				count++;
			}
			if(cur->_type == SUB)
			{
				count += _Size(cur->_sublink);
			}
			cur = cur->_next;
		}
		return count;
	}
	//求广义表的深度
	size_t Depth()
	{
		return _Depth(_head);
	}
	size_t _Depth(Node* head)
	{
		assert(head&&head->_type==HEAD);
		size_t maxSize = 1;
		size_t depth = 1;
		Node* cur = head;
		while(cur)
		{
			if(cur->_type == SUB)
			{
				if(depth+1 > maxSize)
				{
					maxSize = depth+1;
				}
				depth = _Depth(cur->_sublink);
			}
			cur = cur->_next;
		}
		return maxSize;
	}
	//打印函数
	void Print()
	{
		_Print(_head);
		cout<<endl;
	}
	//(a,b,(c,d))
	void _Print(Node* head)
	{
		assert(head&&head->_type==HEAD);
		Node* cur = head;
		cout<<'(';
		while(cur)	
		{
			if(cur->_type == HEAD)
			{
				cur = cur->_next;
			}
			else if(cur->_type == VALUE)
			{
				cout<<cur->_value;
				if(cur->_next)
				{
					cout<<',';
					cur = cur->_next;
				}
				else
				{
					return ;
				}
			}
			else if(cur->_type == SUB)
			{
				_Print(cur->_sublink);
				cout<<')';
				if(cur->_next)
				{
					cout<<',';
					cur = cur->_next;
				}
				else
				{
					break;
				}
			}
		}
			cout<<')';
			
	}
protected:
	Node* _head;
};

/**********测试函数****************/
void Test()
{
	GeneralList g1("(a,b,(c,d))");
	cout<<g1.Size()<<endl;
	cout<<g1.Depth()<<endl;
	g1.Print();

	GeneralList g2(g1);
	g2.Print();
	GeneralList g3;
	g3 = g2;
	g3.Print();
	

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


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值