广义表的创建和遍历

简介:

#include<iostream> 
#include<string>
#include<cstring>
#include<cstdlib>
#include<list>
#include<map>
using namespace std;

class GLNode{
    public:
        int tag;
        string node;
        class {
            public:
                GLNode *hp, *tp;    
        } ptr;
};

typedef GLNode *GList;

class MyGList{
    public:
        static const int ERROR = -1;
        static const int OK = 1;
        static const int LIST = 2;
        static const int NODE = 3;
        list<string> sl;//广义表的描述字符串
        map<string, string>mp;
        GList L = NULL;
        MyGList(list<string> sl){
            this->sl = sl; 
            initMap();
        }
        
        void buildGList(){
            string s = *sl.begin();
            int pos = s.find_first_of("=");
            if(pos!=s.npos)
                createGList(L, s.substr(pos+1, s.length()));
        }
        
        void outGList(){
            out(L);
        }
    
    private:
        void server(string &s, string &hs){
            int k = 0;//记录尚未匹配的左括弧的个数
            int i = 0;
            for(i; i<s.length(); ++i) {
                if(s[i]=='(') ++k;
                if(s[i]==')') --k;
                if(k==0 && s[i]==',') break;
            }
            if(i < s.length()){
                hs = s.substr(0, i);
                s = s.substr(i+1, s.length()-(i+1));
            } else {
                hs = s;
                s = "";
            }
        }
        
        int initMap(){
            for(list<string>::iterator i = sl.begin(); i!=sl.end(); ++i){
                string s = *i, first, second;
                   int pos = s.find_first_of("=");
                   if(pos!=s.npos){
                       first = s.substr(0, pos);
                       second = s.substr(pos+1, s.length());
                   } else {
                       cout<<"广义表的描述字符串出错!"<<endl;
                       return ERROR;
                   }
                mp.insert(make_pair(first, second));
            }
        }
        
        void out(GList Lx){
            if(!Lx) return;
            if(Lx->tag==NODE){
                cout<<Lx->node<<endl;
                return;
            }
            for(GList p=Lx; p; p=p->ptr.tp)
                out(p->ptr.hp);
        }
        
        void createGList(GList &L, string s){
            if(s=="()"){
                //创建空表
                L = NULL; 
            } else { 
                L = new GLNode;//因为类中有string变量,不能用malloc, 否者赋值无效 
                if(s.find(",")==s.npos && s.find("(")==s.npos && s.find(")")==s.npos){//原子结点 
                    if(mp.find(s) == mp.end()){
                        L->tag = NODE;
                        L->node = s;
                    } else {//当s是只有一个大写字母组成的时候,说明它是一个子表,继续扩展 
                        createGList(L, mp[s]);//这块出了开始bug, 调了好长时间 
                    }
                } else {//非原子结点 
                    L->tag = LIST;
                    GList p = L, q;
                    s = s.substr(1, s.length()-2);
                    do{
                        string hs;
                        server(s, hs);//分离表头 
                        createGList(p->ptr.hp, hs);
                        q = p;
                        if(s!=""){//表尾不空 
                            p = new GLNode;
                            p->tag = LIST;
                            q->ptr.tp = p;    
                        }
                    }while(s!="");
                    q->ptr.tp = NULL;
                }
            }
        }
};

int main(){
    freopen("in.txt", "r", stdin);
    list<string> sl;
    string s;
    while(cin>>s){
        sl.push_back(s);
    }
    MyGList myGList(sl);
    myGList.buildGList();
    myGList.outGList();
    return 0;
}


测试数据:
D=(A,B,C)
A=()
B=(e)
C=(a,(b,c,d))

目录
相关文章
|
1月前
|
算法 数据处理 Python
深入理解二叉树:结构、遍历和实现
深入理解二叉树:结构、遍历和实现
深入理解二叉树:结构、遍历和实现
|
9月前
|
Java
java数据结构24:删除数组中的元素(链表)
给定N个整数,将这些整数中与M相等的删除 假定给出的整数序列为:1,3,3,0,-3,5,6,8,3,10,22,-1,3,5,11,20,100,3,9,3 应该将其放在一个链表中,链表长度为20 要删除的数是3,删除以后,链表中只剩14个元素:1 0 -3 5 6 8 10 22 -1 5 11 20 100 9 要求:必须使用链表,不允许使用数组,也不允许不删除元素直接输出
56 0
|
4月前
数据结构单链表之删除给定位置的链表节点 | 第五套
数据结构单链表之删除给定位置的链表节点 | 第五套
38 0
|
7月前
|
存储 算法
二叉树的创建和遍历
二叉树(Binary tree)是树形结构的一个重要类型。许多实际问题抽象出来的数据结构往往是二叉树形式,即使是一般的树也能简单地转换为二叉树,而且二叉树的存储结构及其算法都较为简单,因此二叉树显得特别重要。二叉树特点是每个节点最多只能有两棵子树,且有左右之分
62 0
|
8月前
|
存储 算法 编译器
探索二叉树:结构、遍历与应用
什么是二叉树? 二叉树是一种由节点组成的层次结构,其中每个节点最多有两个子节点,分别称为左子节点和右子节点。这种结构使得二叉树在存储和搜索数据时非常高效。二叉树的一个特殊情况是二叉搜索树(Binary Search Tree,BST),它满足左子节点的值小于父节点,右子节点的值大于父节点,这种特性使得在BST中进行查找操作更加高效。
61 0
|
9月前
链表的遍历
链表的遍历
LeetCode——遍历序列构造二叉树
LeetCode——遍历序列构造二叉树
|
11月前
|
机器学习/深度学习 C++ 容器
二叉树创建和遍历(C++实现)
树(Tree)是n(n≥0)个节点的有限集。在任意一棵树中有且仅有一个特定的称为根(Root)的节点;当n>1时,其余节点可分m(m>0)为个互不相交的有限集T1,T2,...,Tm;其中每一个集合本身又是一棵树,并且称为根的子树(SubTree)。 二叉树(Binary Tree)是一种特殊的有序树型结构,所有节点最多只有2棵子树。
415 0
二叉树的三种遍历方式
二叉树的三种遍历方式
192 0
二叉树的三种遍历方式