广义表的实现
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 }
以上是关于广义表的实现的主要内容,如果未能解决你的问题,请参考以下文章