廣義表的定義ide
廣義表是非線性的結構,是線性表的一種擴展,是有n個元素組成有限序列。函數
廣義表的定義是遞歸的,由於在表的描述中又獲得了表,容許表中有表。測試
例如this
<1> A = ()spa
<2> B = (a,b)blog
<3> C = (a,b,(c,d))遞歸
<4> D = (a,b,(c,d),(e,(f),h)) get
<5> E = (((),())it
廣義表的節點結構定義:io
enum Type { HEAD,//頭結點 VALUE,//數據 SUB,//子表 }; //廣義表結構 struct GeneralizedNode { public: //無參構造函數 GeneralizedNode() :_type(HEAD) ,_next(NULL) {} //有參的構造函數 GeneralizedNode(Type type, char ch); public: Type _type; GeneralizedNode* _next; //由於節點類型不可能既是數據節點又是子表結點,因此採用聯合結構, //節省空間,便於管理。 union { char _value;//數據結點 GeneralizedNode* _subLink;//子表結點 }; }; //有參的構造函數 GeneralizedNode::GeneralizedNode(Type type, char ch = 0) :_type(type) , _next(NULL) { //數據節點則爲數據初始化 if (_type == VALUE) { _value = ch; } //子表結點的初始化 else if (_type == SUB) { _subLink = NULL; } }
廣義表的定義:
注意:因爲廣義表的採用的是用遞歸實現。但構造函數,等成員函數不可以採用遞歸,並且在函數內部須要不斷的傳子表的head,對於成員函數直接使用成員變量_head,則沒法遞歸下去。
//廣義表類 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); } GeneralizedNode* _CopyList(GeneralizedNode* head); //賦值運算符的重載 Generalized& operator=(Generalized g) { swap(_head, g._head); return *this; } //析構函數 ~Generalized() { _Delete(_head); } void _Delete(GeneralizedNode* head); public: //打印廣義表 void Print() { _Print(_head); } //求廣義表的大小 size_t Size() { return _Size(_head); } //求廣義表的深度 size_t Depth() { return _Depth(_head); } protected: //判斷數據是否有效 bool IsVaild(const char ch); //建立廣義表 GeneralizedNode* CreateList(const char* &str); void _Print(GeneralizedNode* head); size_t _Size(GeneralizedNode* head); size_t _Depth(GeneralizedNode* head); private: GeneralizedNode* _head; };
函數的實現
GeneralizedNode* Generalized::_CopyList(GeneralizedNode* head) { GeneralizedNode* cur = head;//須要拷貝的廣義表的當前節點 GeneralizedNode* _head = new GeneralizedNode();//拷貝廣義表的頭結點 GeneralizedNode* index = _head;//拷貝廣義表的當前節點 while (cur) { //數據結點 if (cur->_type == VALUE) { index->_next = new GeneralizedNode(VALUE, cur->_value); index = index->_next; } //子表結點,遞歸複製 else if (cur->_type == SUB) { GeneralizedNode*SubNode = new GeneralizedNode(SUB); index->_next = SubNode; SubNode->_subLink= _CopyList(cur->_subLink); index = index->_next; } cur = cur->_next; } return _head; } void Generalized::_Delete(GeneralizedNode* head) { GeneralizedNode* cur = head; while (cur) { GeneralizedNode* del = cur; //遞歸刪除子表 if (cur->_type == SUB) { _Delete(cur->_subLink); } cur = cur->_next; delete del; } } //判斷廣義表的數據是否合法 bool Generalized::IsVaild(const char ch) { if ((ch >= '0'&&ch <= '9') || (ch >= 'a'&&ch <= 'z') || (ch >= 'A'&&ch <= 'Z')) { return true;//合法 } return false;//非法 } GeneralizedNode* Generalized::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); cur->_next = SubNode; cur = cur->_next; } else if (*str == ')')//廣義表結束 { str++;//返回以前須要給str++指向下一個 return head; } else//空格或者逗號 { str++; } } assert(false); return NULL; } void Generalized::_Print(GeneralizedNode* head) { GeneralizedNode* cur = head; if (cur == NULL) { cout << "()" << endl; return; } while (cur) { if (cur->_type == HEAD) { cout << "("; } else if (cur->_type == VALUE) { cout << cur->_value; //_value不是最後一個值 if (cur->_next) { cout << ","; } } else if (cur->_type == SUB) { _Print(cur->_subLink); if (cur->_next) { cout << ","; } } cur = cur->_next; } //輸出每一個表最後一個( cout << ")"; } size_t Generalized::_Size(GeneralizedNode* head) { GeneralizedNode* cur = head; size_t count = 0; while (cur) { if (cur->_type == VALUE) { count++; } //遞歸求取子表的大小 if (cur->_type == SUB) { count = count + _Size(cur->_subLink); } cur = cur->_next; } return count; } size_t Generalized::_Depth(GeneralizedNode* head) { GeneralizedNode* cur = head; size_t depth = 1;//空表深度爲1 while (cur) { if (cur->_type == SUB) { size_t newDepth = _Depth(cur->_subLink); //若是子表的深度+1大於當前廣義表的最大深度,則更新廣義表的深度 if (newDepth +1 > depth) { depth = newDepth + 1; } } cur = cur->_next; } return depth; }
測試代碼
#include"Generalized.h" void TestGeneralized() { Generalized l("(a,b,(c,d),(e,(f),h))"); Generalized l1; l1 = l; l.Print(); cout << endl; cout << "size:" << l.Size() << endl; cout << "depth:" << l.Depth() << endl; l1.Print(); cout << endl; cout << "size:" << l1.Size() << endl; cout << "depth:" << l1.Depth() << endl; } int main() { TestGeneralized(); getchar(); return 0; }
測試結果