广义表的实现(法二)

#include<iostream>
#include<string>
using namespace std;

enum elemTag {ATOM,LIST}; 
class GList;

class GLnode
{
private:
    elemTag Tag; //标志是原子还是子表 0:原子 1:子表
    union 
    {
        char data; //原子结点值域
        struct //表结点指针域
        {
            GLnode *hp;
            GLnode *tp;
        }ptr;
    };
    friend class GList;
};

class GList
{
public:
    string Decompose(string &str)
    {
        //将非空串str分割成2部分,hstr为第一个','之前的子串,str为后面的
        int n,i,k;
        string ch,hstr;
        n=str.length();
        for(i=0,k=-1;i<n && (ch!="," || k!=0) ;i++)
        {
            //搜索最外层第一个逗号
            ch=str.substr(i,1); //从第i个位置起读1个字符
            if(ch=="(")
                ++k;
            else if(ch==")")
                --k;
        }
        if(i<n)
        {
            hstr=str.substr(1,i-2);//不要左括号,不要逗号,所以是i-2
            str="("+str.substr(i,n-i);
        }
        else
        {
            hstr=str.substr(1,n-2);
            str="";
        }
        return hstr;
    }

    /*----------------------------------------------------
    /从广义表书写形式串S创建采用头尾链表存储表示的广义表T
    /建立广义表头尾结点存储结构的递归定义:
    /基本项:当S为空串时,置空广义表
    /         当S为单字符串时,建立原子结点的子表
    /递归项:假设sub为脱去S最外层括号的子串,记为"s1,s2,s3,..,sn"
    /        每个si为非空字符串,对每个si建立一个表结点
    /--------------------------------------------------------*/

    void Create_GList(GLnode *&GL,string S) //创建广义表
    {
        string hsub;
        if(S=="()") //S为空串
        {
            GL=NULL;
        }
        else
        {
            
            GL=new GLnode;
            if(S.length()==1)
            {
                GL->Tag=ATOM;
                GL->data=S[0];
            }
            else
            {
                GL->Tag=LIST;
                hsub=Decompose(S); //从S中分离出表头串hsub
                Create_GList(GL->ptr.hp,hsub);
                if(S.empty())
                {
                    GL->ptr.tp=NULL;
                }
                else
                {
                    Create_GList(GL->ptr.tp,S);
                }
            }
        }
    }
            
    int GList_Depth(GLnode *GL) //求广义表深度
    {
        /*-----------------------------------------
        /当广义表为空表时,深度为1,当广义表为原子时
        /深度为0,当广义表为广义表时,深度的求法为
        /GList_Depth(GL)=1+max{GList_Depth(lsi)}
        /-----------------------------------------*/

        if(!GL)
            return 1;
        if(GL->Tag==ATOM)
            return 0;
        int dep,max;
        GLnode *p;
        for(max=0,p=GL;p;p=p->ptr.tp)
        {
            dep=GList_Depth(p->ptr.hp);
            if(dep>max)
                max=dep;
        }
        return 1+max;
    }

    void Copy_GList(GLnode *GL,GLnode *&T) //T复制GL
    {
        //当表为空时,复制空表,否则先复制表头在复制表尾
        if(!GL)
            T=NULL;
        else
        {
            T=new GLnode;
            T->Tag=GL->Tag;
            if(GL->Tag==ATOM)
                T->data=GL->data;
            else
            {
                Copy_GList(GL->ptr.hp,T->ptr.hp);
                Copy_GList(GL->ptr.tp,T->ptr.tp);
            }
        }
    }

    /*-----------------------------------------------
    /遍历广义表,如果是空表就输出"()",如果遇到Tag=0
    /的结点,则直接输出该结点的值,如果tag=1,说明
    /是一个子表,首先输出左括号,然后递归调用输出数据
    /元素,并当表尾不空的时候输出逗号,最后输出右括号
    /-----------------------------------------------*/
    void Traverse_GList(GLnode *L)
    {
        if(!L)
            cout<<"()";
        else
        {
            if(L->Tag==ATOM)
                cout<<L->data;
            else
            {
                GLnode *p=NULL;
                cout<<'(';
                p=L;
                while(p)
                {
                    Traverse_GList(p->ptr.hp);
                    p=p->ptr.tp;
                    if(p)
                        cout<<',';
                }
                cout<<')';
            }
        }
    }

    void GetHead(GLnode *GL) //取表头
    {
        //取广义表第一个元素
        cout<<"广义表:";
        Traverse_GList(GL);
        cout<<endl;
        if(!GL || GL->Tag==0 )
            cout<<"原子和空表不能去表头"<<endl;
        else
        {
            GLnode *h=GL->ptr.hp;
            if(h->Tag==ATOM)
                cout<<"表头为:"<<h->data<<endl;
            else
            {
                cout<<"表头为:";
                Traverse_GList(h);
                cout<<endl;
            }
        }
    }
    
    void GetTail(GLnode *GL) //取表尾
    {
        //广义表表尾指的是除了第一个元素后所有剩余的元素组成的表
        cout<<"广义表:";
        Traverse_GList(GL);
        cout<<endl;

        if(!GL || GL->Tag==0)
            cout<<"原子和空表不能取表尾"<<endl;
        else
        {
            GLnode *t;
            t=GL->ptr.tp;
            cout<<"表尾为:";
            Traverse_GList(t);
            cout<<endl;
        }
    }
    
    int Length_GList_1(GLnode *GL) //求表长,非递归
    {
        //用非递归方式求广义表长度
        int len=0;
        if(GL && GL->Tag==LIST)
        {
            while(GL)
            {
                GL=GL->ptr.tp;
                len++;
            }
            return len;
        }
        else
            return 0;
    }

    int Length_GList_2(GLnode *GL) //求表长,递归
    {
        if(!GL)
            return 0;
        return 1+Length_GList_2(GL->ptr.tp);
    }

    void Replace_GList(GLnode *p,char x,char y,GLnode *&q) //替换
    {
        //将广义表p中元素x替换成y,构建新广义表q
        if(!p)
            q=NULL;
        else
        {
            if(p->Tag==ATOM)
            {
                q=new GLnode;
                q->Tag=ATOM;
                q->ptr.hp=NULL;
                if(p->data==x)
                    q->data=y;
                else
                    q->data=p->data;
            }
            else
            {
                GLnode *h,*t;
                Replace_GList(p->ptr.hp,x,y,h);//递归处理表头得到h
                Replace_GList(p->ptr.tp,x,y,t);//递归处理表尾得到t
                q=new GLnode;
                q->Tag=LIST;
                q->ptr.hp=h;
                q->ptr.tp=t;
            }
        }
    }

    int Is_Same(GLnode *p,GLnode *q)//判断是否相等
    {
        int flag=1;//1表示相等,0表示不相等
        if(p && q)
        {
            if(p->Tag==ATOM && q->Tag==ATOM)
            {
                if(p->data!=q->data)
                    flag=0;
                else
                    flag=1;
            }
            else if(p->Tag==LIST &&q->Tag==LIST)
                flag=Is_Same(p->ptr.hp,q->ptr.hp);
            else
                flag=0;
            if(flag)
                flag=Is_Same(p->ptr.tp,q->ptr.tp);
        }
        else
        {
            if(p && !q)
                flag=0;
            if(!p && q)
                flag=0;
        }
        return flag;
    }
    void Concat_Glist(GLnode *&GL,GLnode *LG) //连接两个广义表
    {
        GLnode *p=GL;
        GLnode *q=p->ptr.tp;
        while(q->ptr.tp)
            q=q->ptr.tp;
        q->ptr.tp=LG;
        GL=p;
    }

};

from:http://blog.csdn.net/jkay_wong/article/details/6683989
原文地址:https://www.cnblogs.com/ewitt/p/6648706.html