您好,登錄后才能下訂單哦!
最近學習了廣義表,我們知道廣義表也是一種線性表,而顧名思義廣義表就是不止一個表,下面來舉個栗子:
A=( )
B=(1 , 2,3)
C=(1 ,2 ,3, ( a , b ,c) )
D=(1, 2, 3, (a,( b,c),d),4)
以上A,B,C,D都是廣義表,只不過深度不一樣,也就是括號的對數不一樣,A是個特殊的廣義表,即空表。B里面有三個元素,C里面有6個元素,包括一個子表(a,b,c),C也同理,只不過多了一層子表。由此可總結為一句話:表里有表
這樣看可能不太直觀,下面以廣義表C為例來看一下它的結構圖:
(圖畫得有點丑,不要吐槽我)
每當遇到一個前括號,就要創建一個子表,直到遇見收括號。
那么如何創建一個廣義表呢,在創建節點結構體的時候,我們要考慮每個節點的類型,有可能是頭結
點,也有可能是子表節點,也有可能是普通的值節點,所以在構造節點的時候就要定義一個三元體,由
于是表里有表,我們可以用遞歸的方法來解決廣義表的問題,每個子表都可以遞歸為一個子問題,就可
以很輕松的解決掉這個問題了。
下面是具體實現的代碼:
先構造一個三元結構體:
enum Type { HEAD, VALUE, SUB, }; template<class T> struct GeneralizedNode { Type _type; GeneralizedNode<T>* _next; union { char _value; GeneralizedNode<T>* _sublink; //子表的頭結點 }; public: GeneralizedNode(Type type = HEAD,char value = '\0') :_type(type) ,_next(NULL) { if (type == VALUE) { _value = value; } else if (type == SUB) { _sublink = NULL; } } };
下面來構造一個廣義表類
template<class T> class GeneralizedList { public: GeneralizedList() :_head(new GeneralizedNode<T>(HEAD)) {} GeneralizedList(const char* str) { _head=_CreateList(str); } GeneralizedList(const GeneralizedList& g) //拷貝構造 { _head = Copy(g._head;) } size_t Size() { return size(_head); } size_t depth() { return Depth(_head); } void print() { Print(_head); } protected: GeneralizedNode<T>* _CreateList(const char*& str) { assert(str && *str == '('); ++str; GeneralizedNode<T>* Head = new GeneralizedNode<T>(HEAD,NULL); GeneralizedNode<T>* cur = Head; while (*str) { if (_IsValue(*str)) { cur->_next = new GeneralizedNode<T>(VALUE,*str); cur = cur->_next; str++; } else if (*str == '(') { GeneralizedNode<T>* newNode= new GeneralizedNode<T>(SUB); //將一個子表結點加入到鏈表中 cur->_next = newNode; cur = cur->_next; cur->_sublink = _CreateList(str); str++;//遞歸創建一個子表結點 } else if (*str == ')') //表示一個表已經結束 { str++; return Head; } else { str++; //不需要處理的情況 } } assert(false); return Head; } size_t Depth(GeneralizedNode<T>* head) { GeneralizedNode<T>* cur = head; size_t depth = 1; while (cur) { if (cur->_type == SUB) { size_t subdepth = Depth(cur->_sublink); if (subdepth+1 > depth) { depth=subdepth;//保存較大的深度 } } cur = cur->_next; } return depth; } size_t size(GeneralizedNode<T>* head) { GeneralizedNode<T>* cur = head; size_t count = 0; while (cur) { if (cur->_type != SUB) { count++; } else { count += size(cur->_sublink); } cur = cur->_next; } return count; } void Print(GeneralizedNode<T>* head) { GeneralizedNode<T>* cur = head; while (cur) { if (cur->_type == HEAD) { cout << '('; } else if (cur->_type == VALUE) { cout << cur->_value ; if (cur->_next != NULL) { cout << ',' ; } } else if (cur->_type == SUB) { Print(cur->_sublink); if (cur->_next != NULL) { cout << ','; } } cur = cur->_next; } cout << ')'; } bool _IsValue(char ch) //檢查是否為合法值 { if ((ch >= '0'&&ch<='9') || (ch>='a'&&ch<='z') || (ch>='A'&&ch <= 'Z')) { return true; } return false; } protected: GeneralizedNode<T>* _head; };
下面給出測試代碼:
#include"Generalized.h" void Test() { char* ch = "(a,b,c,(1,2),c)"; GeneralizedList<char> gl1(ch); gl1.print(); cout << endl; cout << "廣義表深度為:" << gl1.depth() << endl; cout << "廣義表大小為:" << gl1.Size() << endl; } int main() { Test(); getchar(); return 0; }
運行結果:
以上就是C++實現廣義表的方法啦,里面也許還存在著一些問題,希望大家能夠指正出來,共同促進學習。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。