1. 程式人生 > >資料結構之廣義表模擬

資料結構之廣義表模擬

測試環境:VS2010

廣義表是一種非線性的結構,是線性表的一種擴充套件,是有n個元素組成有限序列。

廣義表的定義是遞迴的,因為在表的描述中又得到了表,允許表中有表。

eg:

<1> A = ()
<2> B = (a,b)
<3> C = (a,b,(c,d))
<4> D = (a,b,(c,d),(e,(f),h))
<5> E = (((),()))

儲存結構:


程式碼實現:

#include <iostream>
#include <Cassert>
using namespace std;

enum TYPE
{
	HEAD,   //頭型別
	VALUE,  //值型別
	SUB,    //子表型別
};

typedef struct GeneralListNode
{
	GeneralListNode(TYPE type,const char str = 0)//建立節點
		:_type(type)
		,_next(NULL)
	{
		if (type == HEAD || type == VALUE)
		{
			_value = str;
		}
		else if (type == SUB)
		{
			_sublink = NULL;
		}
		else
		{
			assert(false);
		}
	}

	TYPE  _type;             //型別
	GeneralListNode* _next;   //指向同層的下一個節點

	union
	{
		char _value;//值節點的值
		struct GeneralListNode* _sublink;//指向子表的指標
	};


}Node;

class GeneralLized
{
public:
	GeneralLized(const char* str)//建構函式
	{
		 _head = _CreatList(str);
	}
	GeneralLized(const GeneralLized& g)
		:_head(NULL)
	{
		_head = _Copy(g._head);
	}
	////簡潔版的賦值運算子過載1
	//GeneralLized& operator=(GeneralLized g)
	//{
	//	swap(_head,g._head);
	//	return *this;
	//}
	//簡潔版的賦值運算子過載2
	GeneralLized& operator=(const GeneralLized& g)
	{
		Node* tmp = _Copy(g._head);
		_Destroy(_head);
		swap(_head,tmp);
		
		return *this;
	}
	~GeneralLized()
	{
		if (NULL != _head)
		{
			_Destroy(_head);
			_head = NULL;
		}
	}
	void PrintGeneralLized()//列印廣義表
	{
		_Print(_head);
		cout<<endl;
	}
	size_t Size()//求值節點個數
	{
		return _Size(_head);
	}
	size_t Depth()//廣義表的深度
	{
		return _Depth(_head);
	}
protected:
	bool IsValue(const char& s)//判斷是否是有效值
	{
		if (   (s >= '0' && s <= '9')
			|| (s >= 'a' && s >= 'z')
			|| (s >= 'A' && s >= 'Z'))
		{
			return true;
		}
		return false;
	}
	Node* _CreatList(const char*& s)//建立廣義表
	{
		assert(*s == '(');//斷言第一個字元必須是'('
		s++;//s向後偏移1,跳過'('
		Node* head = new Node(HEAD);//建立新節點
		Node* cur = head;//建立當前節點來插入新資料

		while(*s)
		{
			if (IsValue(*s))//值節點
			{
				cur->_next = new Node(VALUE,*s);//建立資料節點
				cur = cur->_next;
				s++;
			}
			else if (*s == '(')//子表
			{
				Node* newNode = new Node(SUB);//新建子表節點
				cur->_next = newNode;//尾插子表節點
				cur = cur->_next;
				newNode->_sublink = _CreatList(s);//遞迴建立子表
			}
			else if (*s == ')')//子表結束
			{
				s++;
				return head;
			}
			else
			{
				s++;
			}
		}
		return head;
	}
	Node* _Copy(Node* head)
	{
		Node* cur = head;
		Node* newHead = new Node(HEAD);//新廣義表的頭節點
		Node* newCur = newHead;//新廣義表的當前節點
		cur = cur->_next;//跳過頭節點

		while(cur)
		{
			if (cur->_type == VALUE)//值節點
			{
				newCur->_next = new Node(VALUE,cur->_value);//建立新的值節點
				cur = cur->_next;
				newCur = newCur->_next;
			}
			else if (cur->_type == SUB)//子表節點
			{
				Node* newSub = new Node(SUB);//新建子表節點
				newCur->_next = newSub;
				newCur = newCur->_next;
				newSub->_sublink = _Copy(cur->_sublink);//遞迴拷貝子表
				cur = cur->_next;
			}
			else
			{
				assert(false);
			}
		}
		return newHead;
	}
	void _Destroy(Node* head)
	{
		Node* cur = head;
		Node* del = cur;

		while (cur)
		{
			if (cur->_type == SUB)//子表節點
			{
				del = cur;
				cur = cur->_next;
				_Destroy(del->_sublink);
				delete del;
			}
			else//值節點or頭節點
			{
				del = cur;
				cur = cur->_next;
				delete del;
			}
		}
	}
	Node* _Print(Node* head)//列印廣度表
	{
		Node* cur = head;
		while(cur)
		{
			if (cur->_type == HEAD)//頭結點直接列印'('
			{
				cout<<'(';
			}
			else if (cur->_type == VALUE)//值節點
			{
				cout<<cur->_value;
				if (NULL != cur->_next)//子表未結束時,用','分割資料
				{
					cout<<',';
				}
			}
			else if (cur->_type == SUB)//子表項
			{
				_Print(cur->_sublink);//遞迴列印子表
				if (NULL != cur->_next)//子表結項束時,用','分割
				{
					cout<<',';
				}
			}
			else
			{
				assert(false);
			}
			cur = cur->_next;
		}
		cout<<')';
		return head;
	}
	size_t _Size(Node* head)//資料節點的個數
	{
		size_t count = 0;
		Node* cur = head;
		while(cur)
		{
			if (cur->_type == VALUE)//若為值節點則count++
			{
				count++;
			}
			else if (cur->_type == SUB)//若為子表節點,則count+=子表資料節點
			{
				count += _Size(cur->_sublink);
			}
			else
			{
				;
			}
			
			cur = cur->_next;
		}
		return count;
	}
	size_t _Depth(Node* head)//求取廣義表深度
	{
		Node* cur = head;   
		size_t maxDepth = 1;//頭節點不為空,則深度為1

		while(cur)
		{
			if (cur->_type == SUB)//子表
			{
				if (maxDepth < _Depth(cur->_sublink) + 1)//當前深度為子表項深度+1
				{
					maxDepth = _Depth(cur->_sublink) + 1;//更新子表項
				}
			}
			cur = cur->_next;
		}
		return maxDepth;
	}
protected:
	Node* _head;//廣義表的頭結點
};

void TestGeneralLized()
{
	char* s = "()";//空表
	GeneralLized g(s);
	g.PrintGeneralLized();
	cout<<"size:"<<g.Size()<<endl;
	cout<<"depth:"<<g.Depth()<<endl;
	cout<<endl;
	
	char* s1 = "(a,b)";
	GeneralLized g1(s1);
	g1.PrintGeneralLized();
	cout<<"size:"<<g1.Size()<<endl;
	cout<<"depth:"<<g1.Depth()<<endl;
	cout<<endl;

	char* s2 = "(a,b,(c,d))";
	GeneralLized g2(s2);
	g2.PrintGeneralLized();
	cout<<"size:"<<g2.Size()<<endl;
	cout<<"depth:"<<g2.Depth()<<endl;
	cout<<endl;

	char* s3 = "(a,b,(c,d),(e,(f),h))";
	GeneralLized g3(s3);
	g3.PrintGeneralLized();
	cout<<"size:"<<g3.Size()<<endl;
	cout<<"depth:"<<g3.Depth()<<endl;
	cout<<endl;

	char* s4 = "(((),()))";
	GeneralLized g4(s4);
	g4.PrintGeneralLized();
	cout<<"size:"<<g4.Size()<<endl;
	cout<<"depth:"<<g4.Depth()<<endl;
	cout<<endl;

	GeneralLized g5(g3);
	g5.PrintGeneralLized();
	cout<<"size:"<<g5.Size()<<endl;
	cout<<"depth:"<<g5.Depth()<<endl;
	cout<<endl;

	g4 = g2;//賦值運算子測試
	g4.PrintGeneralLized();
	cout<<"size:"<<g4.Size()<<endl;
	cout<<"depth:"<<g4.Depth()<<endl;
	cout<<endl;
}

int main()
{
	TestGeneralLized();
	system("pause");
	return 0;
}
執行結果: