資料結構之廣義表模擬
阿新 • • 發佈:2019-01-03
測試環境: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; }