廣義表是非線性的結構,是線性表的一種擴展,是有n個元素組成有限序列。
廣義表的定義是遞歸的,因爲在表的描述中又得到了表,允許表中有表。
<1> A = ()
<2> B = (a,b)
<3> C = (a,b,(c,d))
<4> D = (a,b,(c,d),(e,(f),h))
<5> E = (((),()))
如下圖所示:
廣義表主要使用遞歸實現,表與表之間使用鏈式結構來存儲。下面就來看看代碼怎樣實現的:
#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
//節點類型
enum Type
{
HEAD,//頭節點
VALUE,//數據項
SUB,//子表的頭節點
};
//廣義表結構
struct GeneralizedNode
{
public:
GeneralizedNode()//無參構造函數
:_type(HEAD)
, _next(NULL)
{}
GeneralizedNode(Type type, char ch = 0)
:_type(type)
,_next(NULL)
{
if (_type == VALUE)
{
_value = ch;//數據節點
}
if (_type == SUB)
{
_sublink = NULL;//子表節點
}
}
public:
Type _type;//節點類型
GeneralizedNode * _next;
union
{
char _value;//數據
GeneralizedNode * _sublink;//子表的頭指針
};
};
//廣義表類
class Generalized
{
public:
Generalized()//無參構造函數
:_head(new GeneralizedNode(HEAD))
{}
Generalized(const char* str)//構造函數
:_head(NULL)
{
_head = _CreateList(str);
}
Generalized(const Generalized & g)//拷貝構造
{
_head = _CopyList(g._head);
}
Generalized& operator=(Generalized g)//賦值運算符的重載
{
swap(_head, g._head);//現代寫法
return *this;
}
~Generalized()//析構函數
{
_Delete(_head);//遞歸析構
}
public:
void print()//打印
{
_Print(_head);
}
size_t size()//元素個數
{
size_t ret=_Size(_head);
return ret;
}
size_t depth()//廣義表的深度
{
size_t ret=_Depth(_head);
return ret;
}
public:
GeneralizedNode * _CreateList(const char* &str)//創建廣義表
{
assert(str&&*str == '(');
//判斷傳入的廣義表是否正確
str++;//跳過'('
GeneralizedNode* head = new GeneralizedNode();//創建頭節點
GeneralizedNode* cur = head;
while (*str)
{
if (_IsVaild(*str))
{
cur->_next = new GeneralizedNode(VALUE, *str);//創建數據節點
cur = cur->_next;//節點後移
str++;//指針後移
}
else if (*str == '(')//子表
{
GeneralizedNode* SubNode = new GeneralizedNode(SUB);//創建字表的頭節點
SubNode->_sublink = _CreateList(str);//遞歸調用_CreateList函數
cur->_next = SubNode;
cur = cur->_next;
}
else if (*str == ')')//表的結束
{
str++;//跳過')'
return head;//返回頭節點
}
else//其他字符(' '或者',')
{
str++;
}
}
assert(false);//強制判斷程序是否出錯
return head;
}
bool _IsVaild(const char ch)//判斷輸入是否合理
{
if ((ch >= '0'&&ch <= '9')
|| (ch >= 'a'&&ch <= 'z')
|| (ch >= 'A'&&ch <= 'Z'))
{
return true;
}
else
{
return false;
}
}
GeneralizedNode* _CopyList(GeneralizedNode* head)//複製
{
GeneralizedNode* cur = head;
//創建新的頭節點
GeneralizedNode* newHead = new GeneralizedNode();
GeneralizedNode* tmp = newHead;
while (cur)
{
if (cur->_type == VALUE)//數據節點
{
tmp->_next = new GeneralizedNode(VALUE, cur->_value);
tmp = tmp->_next;
}
else if (cur->_type == SUB)//子表節點
{
GeneralizedNode* SubNode = new GeneralizedNode(SUB);
tmp->_next = SubNode;
SubNode->_sublink = _CopyList(cur->_sublink);//遞歸調用
tmp = tmp->_next;
}
cur = cur->_next;
}
return newHead;
}
void _Delete(GeneralizedNode * head)
{
GeneralizedNode* cur = head;
while (cur)
{
GeneralizedNode* del = cur;
if (cur->_type == SUB)//子表節點時遞歸析構
{
_Delete(cur->_sublink);
}
cur = cur->_next;
delete del;
}
}
void _Print(GeneralizedNode* head)//打印
{
GeneralizedNode* cur = head;
if (cur == NULL)
{
return;
}
while (cur)
{
if (cur->_type == HEAD)
{
cout << "(";
}
else if (cur->_type == VALUE&&cur->_next)
{
cout << cur->_value<<",";
}
else if (cur->_type == VALUE&&cur->_next == NULL)
{
cout << cur->_value;
}
else if (cur->_type == SUB)
{
_Print(cur->_sublink);
if (cur->_next)
{
cout << ",";
}
}
cur = cur->_next;
}
if (cur == NULL)
{
cout << ")";
return;
}
}
size_t _Size(GeneralizedNode* head)//元素的個數
{
GeneralizedNode* cur = head;
size_t count = 0;
while (cur)
{
if (cur->_type == VALUE)
{
count++;
}
else if (cur->_type == SUB)
{
count += _Size(cur->_sublink);
}
cur = cur->_next;
}
return count;
}
size_t _Depth(GeneralizedNode* head)//廣義表的深度
{
GeneralizedNode* cur = head;
size_t depth = 1;
while (cur)
{
if (cur->_type == VALUE)
{
depth++;
}
else if (cur->_type == SUB)
{
size_t newdepth = _Depth(cur->_sublink);
if (newdepth++ > depth)//當後面子表的深度比現在的深時,更新深度
{
depth = newdepth++;
}
}
cur = cur->_next;
}
return depth;
}
private:
GeneralizedNode * _head;
};
測試代碼和結果如下:
void Test()
{
Generalized g1("(a,b(c,d),(e,(f),h))");
Generalized g2;
g1.print();
cout << endl;
cout << "g1.size()="<< g1.size() << endl << endl;
cout << "g1.depth()=" << g1.depth() << endl << endl;
g2 = g1;
g2.print();
cout << endl;
cout << "g2.size()=" << g1.size() << endl << endl;
cout << "g2.depth()=" << g1.depth() << endl << endl;
}
本文出自 “不斷進步的空間” 博客,請務必保留此出處http://10824050.blog.51cto.com/10814050/1766411