您好,登錄后才能下訂單哦!
廣義表是非線性的結構,是線性表的一種擴展,是有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; }
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。