zoukankan      html  css  js  c++  java
  • 广义表的实现

      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 }
  • 相关阅读:
    数组作为方法参数
    定义一个方法,根据商品总价,计算出对应的折扣并输出。折扣信息如下
    Cocos2d入门--1--初涉相关属性或代码
    JSP基础--JAVA遇见HTML
    查找算法--折半查找
    排序算法--冒泡排序
    排序算法--简单选择排序
    C语言的传值与传址调用
    学习C语言的数组
    如何获取QQ里的截图app?
  • 原文地址:https://www.cnblogs.com/Serenaxy/p/11785501.html
Copyright © 2011-2022 走看看