广义表的基本实现

 广义表是线性表的一种推广。下边通过几个例子说明一下广义表:

A=(),A是一个空表,长度为0,深度为0.

B=(m),B中只有一个元素m,长度为1,深度为1.

C=(a,(b,c),d)有4个元素,长度为4,深度为2.

广义表的存储:


由于广义表的深度我们无法预知,当然不可以采用循环,所以用递归实现咯。

下边来看看实现代码:

#pragma once
#include<iostream>
using namespace std;
#include<assert.h>

enum Type
{
	_HEAD_TYPE,
	_VALUE_TYPE,
	_SUB_TYPE
};
struct GeneralizedNode
{
	Type _type;
	struct GeneralizedNode* _next;
	union
	{
		int _value;
		struct GeneralizedNode* _sublink;
	};
	GeneralizedNode(Type type)
	{
		_type = type;
	}
};

class Generalized
{
public:
	Generalized()
		:_head(NULL)
	{}

	Generalized(char* str)
		:_head(NULL)
	{
		_head = Create(str);
	}
	~Generalized()
	{
		_Destroy(_head);
	}
	void Print()
	{
		_Print(_head);
		cout << endl;
	}
	size_t Size()
	{
		size_t count = _Size(_head);
		return count;
	}
	size_t Depth()
	{
		size_t depth = _Depth(_head);
		return depth;
	}
	Generalized(const Generalized& g)
	{
		_head = _Copy(g._head);
	}
	//现代写法
	/*Generalized& operator=(Generalized g)
	{
		std::swap(_head,g._head);
		return *this;
	}*/
	//传统写法
	Generalized& operator=(const Generalized& g)
	{
		if (this != &g)
		{
			GeneralizedNode* head = _Copy(g._head);
			_Destroy(_head);
			_head = head;
		}
		return *this;
	}
protected:
	void _Destroy(GeneralizedNode* _head)
	{
		GeneralizedNode* cur = _head;
		while (cur)
		{
			GeneralizedNode* del = cur;
			if (del->_type == _SUB_TYPE)
			{
				_Destroy(cur->_sublink);
			}
			cur = cur->_next;
			delete del;
		}
	}
	GeneralizedNode* _Copy(GeneralizedNode* head)
	{
		GeneralizedNode* cur = head->_next;//遍历原表
		GeneralizedNode* NewHead = new GeneralizedNode(_HEAD_TYPE);//指向新表
		GeneralizedNode* pre = NewHead;
		GeneralizedNode* NewNode;

		while (cur)
		{
			if (cur->_type == _SUB_TYPE)
			{
				NewNode = new GeneralizedNode(_SUB_TYPE);

				NewNode->_sublink = _Copy(cur->_sublink);
				pre->_next = NewNode;
				/*pre = NewNode;
				cur = cur->_next;*/
			}
			else if(cur->_type == _VALUE_TYPE)
			{
				NewNode = new GeneralizedNode(_VALUE_TYPE);
				NewNode->_type = _VALUE_TYPE;
				NewNode->_value = cur->_value;

				//NewCur->_next = NewNode;
				pre->_next = NewNode;
				//NewCur = NewNode;
				/*NewCur = NewCur->_next;*/

				/*pre = pre->_next;
				cur = cur->_next;*/
			}
			cur = cur->_next;
			pre = pre->_next;
		}
		pre->_next = NULL;
		return NewHead;
	}
	size_t _Depth(GeneralizedNode* head)
	{
		GeneralizedNode* cur = head;
		size_t maxDepth = 1;
		while (cur)
		{
			size_t depth  = 1;
			if (cur->_type == _SUB_TYPE)
			{
				depth = _Depth(cur->_sublink)+1;
				if (depth > maxDepth)
				{
					maxDepth = depth;
				}
			}
			cur = cur->_next;
		
		}
		return maxDepth;
	}
	void _Print(GeneralizedNode* head)
	{
		cout << "(";
		GeneralizedNode* cur = head;

		while (cur)
		{
			if (cur->_type == _VALUE_TYPE)
			{
				cout << cur->_value;
				if (cur->_next != NULL)
				{
					cout << ",";
				}
				cur = cur->_next;
			}
			else if (cur->_type == _SUB_TYPE)
			{
				_Print(cur->_sublink);
				if (cur->_next != NULL)
				{
					cout << ",";
				}
				cur = cur->_next;
			}
			else
			{
				cur = cur->_next;
			}
		}
		cout << ")";
		
	}
	size_t _Size(GeneralizedNode* &head)
	{
		GeneralizedNode* cur = head;
		size_t count = 0;
		while (cur)
		{
			if (cur->_type == _VALUE_TYPE)
			{
				++count;
				cur = cur->_next;
			}
			else if (cur->_type == _SUB_TYPE)//子表
			{
				count += _Size(cur->_sublink);
				cur = cur->_next;
			}
			else
			{
				cur = cur->_next;
			}
		}
		return count;
	}
	bool isValue(char  c)
	{
		//if (isalpha(c))//小写字母,大写字母
		if((c >= 'a'&&c<= 'z')|| (c >= 'A'&&c <= 'Z'))
			return true;
		else
			return false;
	}
	GeneralizedNode* Create(char* &str)
	{
		assert(*str == '(');
		str++;
		GeneralizedNode* head = new GeneralizedNode(_HEAD_TYPE);
		GeneralizedNode* prev = head;
		GeneralizedNode* cur = NULL;
		head->_next = cur;

		while (*str)
		{
			if (isValue(*str))//字母字符
			{
				cur = new GeneralizedNode(_VALUE_TYPE);
				cur->_value = *str;
				prev->_next = cur;
				str++;
				prev = cur;
			}
			else if (*str == '(')
			{
				GeneralizedNode* pLink = new GeneralizedNode(_SUB_TYPE);
				prev->_next = pLink;

				//cur = cur->_next;
				cur = Create(str);
				pLink->_sublink = cur;

				prev = pLink;
			}
			else if (*str == ')')
			{
				prev->_next = NULL;
				str++;
				return head;
			}
			else
			{
				str++;
			}
		}
		return head;
	}
public:
	GeneralizedNode* _head;
};

void TestGeneralized()
{
	Generalized s1("()");
	Generalized s2("(a,b)");
	Generalized s3("(a,b,(c,d))");
	Generalized s4("(a,b,(c,d),e)");
	Generalized s5("(a,b,(c,(),d),e)");
	Generalized s6(s3);
	s1 = s2;
	s1.Print();
	s2.Print();
	s3.Print();
	s4.Print();
	s6.Print();
	cout << s1.Size() << endl;
	cout << s2.Size() << endl;
	cout << s3.Size() << endl;
	cout << s4.Size() << endl;
	cout << s1.Depth() << endl;
	cout << s2.Depth() << endl;
	cout << s3.Depth() << endl;
	cout << s4.Depth() << endl;
	cout << s5.Depth() << endl;
}


结点的定义中使用了枚举类型,原因如下:

结点有三种类型,值类型,头结点类型和子表 结点类型,而这三种结点公共的属性就是

每个结点都有自己的type(类型),也有自己的next域,值结点有自己的value,子表结

点有自己的_sublink,所以,这个可以定义成共用体类型,节省空间。

由于广义表需要用到递归,而类的成员函数最好不要递归(因为类的成员函数是内联函

数)

内联函数的特点:

在函数的调用处直接展开,减少了函数调用过程中的压栈开销所以,代码很长或者有

环,递归就尽量不要内联。

内联对于编译器而言只是一个建议,编译器会自动优化,如果内联函数内有循环或者

归,编译器会忽略内联。

inline必须和函数的定义放在一起。

下边再来简述一下operator=函数

两种实现办法:

传统的方法  ------避免自赋值;先构造,再释放(防止构造时申请空间失败) 

现代写法------一种是代码中写的那样

                     交换之后,原来空间的内容就会保存在那个形参变量中,离开作用域自动                            析构

              --------另一种是传引用。代码如下:

<pre name="code" class="cpp">GeneralizedNode* operator=(const Generalized& g)
{
        if(&g != this)
        {
                Generalized<T>  tmp(g);
                swap(_head,tmp._head);
        }
return *this;
}


 


好了,广义表就到这里~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值