广义表的实现

Posted serenaxy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了广义表的实现相关的知识,希望对你有一定的参考价值。

  1 #pragma once
  2 #include <iostream>
  3 #include <vector>
  4 #include <algorithm>
  5 using namespace std;
  6 
  7 template <class T>
  8 struct GenListNode;
  9 
 10 template <class T>
 11 struct Item {    //广义表结点的值项
 12     int utype;
 13     union {
 14         int ref = 0;
 15         T value;
 16         GenListNode<T> * hlink;
 17 
 18     }info;
 19     Item() : utype(0) {}
 20     Item(const Item & other) {
 21         utype = other.utype;
 22         info = other.info;
 23     }
 24 };
 25 
 26 template <class T>
 27 struct GenListNode {
 28     Item<T> item;
 29     GenListNode<T> * tlink;
 30     GenListNode() : item(), tlink(nullptr) {}
 31     GenListNode(const GenListNode<T> & other) : item(other.item), tlink(other.tlink) {}
 32 };
 33 
 34 template <class T>
 35 class GenList {
 36 private:
 37     //成员域
 38     GenListNode<T> * first;
 39 public:
 40     //构造方法
 41     GenList();
 42     GenList(const GenList<T> & other);
 43     ~GenList();
 44     //成员方法
 45     bool getHead(Item<T> & x); //获取第一个元素的值域
 46     bool getTail(GenList<T> & subList); //获取表尾
 47     GenListNode<T> * head();   //返回第一个元素
 48     GenListNode<T> * Next(GenListNode<T> * cur); //返回当前元素的下一个元素
 49     int lenth(); //返回广义表的长度
 50     int depth(); //返回广义表的深度
 51     GenList<T> & operator = (const GenList<T> & other); //广义表复制
 52     bool operator == (const GenList<T> & other); //比较广义表是否相等
 53     void input();   //输入
 54     void output();  //输出
 55 private:
 56     //工具函数
 57     void remove(GenListNode<T> * Is);
 58     GenListNode<T> * copy(GenListNode<T> * Is, vector<GenListNode<T> *> &mv, vector<GenListNode<T> *> &ov);
 59     int lenth(GenListNode<T> * Is);
 60     int depth(GenListNode<T> * Is, vector<GenListNode<T> *>& v);
 61     bool equal(GenListNode<T> * s, GenListNode<T> * t, vector<GenListNode<T> *>& v1, vector<GenListNode<T> *>& v2);
 62     void input(GenListNode<T> * &Is, vector<char> & v1, vector<GenListNode<T> *> & v2); //创建Is指向的广义表
 63     void output(GenListNode<T> * Is, vector<char> & v1, vector<GenListNode<T> *> & v2, char & c); //输出由Is指向的广义表
 64 };
 65 
 66 template<class T>
 67 inline GenList<T>::GenList()
 68 {
 69     first = new GenListNode<T>();
 70 }
 71 
 72 template<class T>
 73 inline GenList<T>::GenList(const GenList<T>& other)
 74 {
 75     vector<GenListNode<T> *> v1, v2;
 76     first = copy(other.first, v1, v2);
 77 }
 78 
 79 template<class T>
 80 inline GenList<T>::~GenList()
 81 {
 82     remove(first);
 83 }
 84 
 85 template<class T>
 86 inline bool GenList<T>::getHead(Item<T>& x)
 87 {
 88     if (first->tlink == nullptr)
 89         return false;
 90     x = first->tlink->item;
 91     return true;
 92 }
 93 
 94 template<class T>
 95 inline bool GenList<T>::getTail(GenList<T>& subList)
 96 {
 97     if (first->tlink == nullptr)
 98         return false;
 99     remove(subList.first);
100     vector<GenListNode<T> *> v1, v2;
101     subList.first = new GenListNode<T>();
102     subList.first->tlink = copy(first->tlink->tlink, v1, v2);
103     return true;
104 }
105 
106 template<class T>
107 inline GenListNode<T>* GenList<T>::head()
108 {
109     return first->tlink;
110 }
111 
112 template<class T>
113 inline GenListNode<T>* GenList<T>::Next(GenListNode<T>* cur)
114 {
115     return cur->tlink;
116 }
117 
118 template<class T>
119 inline int GenList<T>::lenth()
120 {
121     return lenth(first);
122 }
123 
124 template<class T>
125 inline int GenList<T>::depth()
126 {
127     vector<GenListNode<T> *> v;
128     return depth(first, v);
129 }
130 
131 template<class T>
132 inline GenList<T>& GenList<T>::operator=(const GenList<T>& other)
133 {
134     vector<GenListNode<T> *> v1, v2;
135     remove(first);
136     first = copy(other.first, v1, v2);
137     return *this;
138 }
139 
140 template<class T>
141 inline bool GenList<T>::operator==(const GenList<T>& other)
142 {
143     vector<GenListNode<T> *> v1, v2;
144     return equal(first, other.first, v1, v2);
145 }
146 
147 template<class T>
148 inline void GenList<T>::input()
149 {
150     remove(first);
151     first = nullptr;
152     vector<char> v1;
153     vector<GenListNode<T> *> v2;
154     input(first, v1, v2);
155 }
156 
157 template<class T>
158 inline void GenList<T>::output()
159 {
160     char c = 64;
161     vector<char> v1;
162     vector<GenListNode<T> *> v2;
163     output(first, v1, v2, c);
164 }
165 
166 template<class T>
167 inline void GenList<T>::remove(GenListNode<T>* Is)
168 {
169     while (Is != nullptr) {
170         GenListNode<T> * del = Is;
171         Is = Is->tlink;
172         if ((del->item.utype == 0 && del->item.info.ref == 0)
173             || del->item.utype == 1)
174             delete del;
175         else if (del->item.utype == 0 && del->item.info.ref > 0)
176             del->tlink = nullptr;
177         else if(del->item.utype == 2){
178             --del->item.info.hlink->item.info.ref;
179             remove(del->item.info.hlink);
180             delete del;
181         }
182     }
183 }
184 
185 template<class T>
186 inline GenListNode<T>* GenList<T>::copy(GenListNode<T>* Is, vector<GenListNode<T> *> &mv, vector<GenListNode<T> *> &ov)
187 {
188     //特殊处理
189     if (Is == nullptr)
190         return nullptr;
191     auto i = find(ov.begin(), ov.end(), Is);
192     if (i != ov.end()) {  //已经复制
193         return mv.at(i - ov.begin());
194     }
195     else {  //未复制
196         GenListNode<T> * It = new GenListNode<T>(*Is); //复制附加头结点
197         //存放附加头节点信息
198         mv.push_back(It);
199         ov.push_back(Is);
200         //复制同一层结点
201         Is = Is->tlink;
202         GenListNode<T> *cur = It;
203         while (Is != nullptr) {
204             //复制Is指向结点(并插入cur后)
205             cur->tlink = new GenListNode<T>(*Is);
206             if (Is->item.utype == 2) {
207                 cur->tlink->item.info.hlink = copy(Is->item.info.hlink, mv, ov);
208             }
209             //更新
210             cur = cur->tlink;
211             Is = Is->tlink;
212         }
213         return It;
214     }
215 }
216 
217 template<class T>
218 inline int GenList<T>::lenth(GenListNode<T>* Is)
219 {
220     if (Is == nullptr)
221         return -1;
222     return lenth(Is->tlink) + 1;
223 }
224 
225 
226 template<class T>
227 inline int GenList<T>::depth(GenListNode<T>* Is, vector<GenListNode<T> *>& v)
228 {
229     //求表中结点的最大深度
230     int max = 0;
231     while (Is != nullptr) {  //遍历每一个结点
232         if (Is->item.utype == 2) {
233             //异常情况
234             auto i = find(v.begin(), v.end(), Is);
235             if (i != v.end()) {
236                 cerr << "该表无法求深度";
237                 system("pause");
238                 exit(1);
239             }
240             v.push_back(Is);
241             int temp = depth(Is->item.info.hlink, v);
242             if (temp > max)
243                 max = temp;
244         }
245         Is = Is->tlink;
246     }
247     return max + 1;
248 }
249 
250 template<class T>
251 inline bool GenList<T>::equal(GenListNode<T>* s, GenListNode<T>* t, vector<GenListNode<T> *>& v1, vector<GenListNode<T> *>& v2)
252 {
253     if (s == nullptr || t == nullptr) {
254         if (s == t)
255             return true;
256     }
257     else if (s->item.utype == t->item.utype) {
258         if (s->item.utype == 0) {
259             if(s->item.info.ref == t->item.info.ref){
260                 v1.push_back(s);
261                 v2.push_back(t);
262                 return equal(s->tlink, t->tlink, v1, v2);
263             }
264         }
265         else if (s->item.utype == 1) {
266             if (s->item.info.value == t->item.info.value)
267                 return equal(s->tlink, t->tlink, v1, v2);
268         }
269         else {
270             auto i = find(v1.begin(), v1.end(), s->item.info.hlink);
271             auto j = find(v2.begin(), v2.end(), t->item.info.hlink);
272             if (i == v1.end() && j == v2.end()) {
273                 return equal(s->item.info.hlink, t->item.info.hlink, v1, v2);
274                 return equal(s->tlink, t->tlink, v1, v2);
275             }
276             else if(i-v1.begin() == j-v2.begin()){
277                 return equal(s->tlink, t->tlink, v1, v2);
278             }
279         }
280     }
281     return false;
282 }
283 
284 
285 template<class T>
286 inline void GenList<T>::input(GenListNode<T>*& Is, vector<char>& v1, vector<GenListNode<T>*>& v2)
287 {
288     T chr;
289     cin >> chr;
290     //特殊情况
291     if (first == nullptr) {
292         //异常处理
293         if (chr != ( && !(isalpha(chr) && isupper(chr))) {
294             cerr << "错误";
295             system("pause");
296             exit(1);
297         }
298         Is = new GenListNode<T>();
299         if (isalpha(chr) && isupper(chr)) {
300             v1.push_back(chr);
301             v2.push_back(Is);
302             cin >> chr;
303             //异常处理
304             if (chr != () {
305                 cerr << "错误";
306                 system("pause");
307                 exit(1);
308             }
309         }
310         input(Is->tlink, v1, v2);
311         return;
312     }
313     else if ((isalpha(chr) && isupper(chr)) || chr == () {
314         //创建2类结点
315         Is = new GenListNode<T>();
316         Is->item.utype = 2;;
317         if (isalpha(chr) && isupper(chr)) { //A()
318             auto i = find(v1.begin(), v1.end(), chr);
319             if (i == v1.end()) { //还没有创建过该子表
320                 Is->item.info.hlink = new GenListNode<T>();
321                 ++Is->item.info.hlink->item.info.ref;
322                 v1.push_back(chr);
323                 v2.push_back(Is->item.info.hlink);
324                 cin >> chr;
325                 if (chr != () {
326                     cerr << "错误";
327                     system("pause");
328                     exit(1);
329                 }
330                 input(Is->item.info.hlink->tlink, v1, v2);
331                 input(Is->tlink, v1, v2);
332             }
333             else {  //创建过了
334                 GenListNode<T> * sub = v2[i - v1.begin()];
335                 ++sub->item.info.ref;
336                 Is->item.info.hlink = sub;
337                 //异常处理
338                 if (cin.peek() != ) && cin.peek() != ,) {
339                     cerr << "错误";
340                     system("pause");
341                     exit(1);
342                 }
343                 input(Is->tlink, v1, v2);
344             }
345         }
346         else { //( )
347             //创建子广义表的附加头结点
348             Is->item.info.hlink = new GenListNode<T>();
349             ++Is->item.info.hlink->item.info.ref;
350             input(Is->item.info.hlink->tlink, v1, v2);
351             input(Is->tlink, v1, v2);
352         }
353     }
354     else if (isalpha(chr) && islower(chr)) {
355         //创建1类结点
356         Is = new GenListNode<T>();
357         Is->item.utype = 1;
358         Is->item.info.value = chr;
359         input(Is->tlink, v1, v2);
360     }
361     else if (chr == ,)
362         input(Is, v1, v2);
363 }
364 
365 template<class T>
366 inline void GenList<T>::output(GenListNode<T>* Is, vector<char> & v1, vector<GenListNode<T>*> & v2, char & c)
367 {
368     //边界
369     if (Is == nullptr)
370         cout << );
371     else if (Is->item.utype == 0) {  //类型0结点
372         auto i = find(v2.begin(), v2.end(), Is);
373         if (i == v2.end()) { //没有输出过该子表
374             ++c;
375             cout << c << (;
376             v1.push_back(c);
377             v2.push_back(Is);
378             output(Is->tlink, v1, v2, c);
379         }
380         else {  //输出过该子表
381             cout << v1.at(i - v2.begin());
382         }
383     }
384     else if (Is->item.utype == 1) { //类型1结点
385         cout << Is->item.info.value;
386         if (Is->tlink != nullptr)
387             cout << ", ";
388         output(Is->tlink, v1, v2, c);
389     }
390     else {   //类型2结点
391         output(Is->item.info.hlink, v1, v2, c);
392         if (Is->tlink != nullptr)
393             cout << ", ";
394         output(Is->tlink, v1, v2, c);
395     }
396 }

 

以上是关于广义表的实现的主要内容,如果未能解决你的问题,请参考以下文章

广义表的实现

广义表的实现

广义表的实现(法二)

用非递归方法实现共享表运算

广义表的概念及存储表示

数据结构:广义表转置