• 广义表的实现(法二)


    #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
  • 相关阅读:
    SQLServer两张表筛选相同数据和不同数据
    Js工具
    检测本地字节序 是大端存储还是小端存储
    C++ 一个统计文件夹下所有代码文件行数的小工具
    C++ 扫描文件夹下所有文件
    C++ 安全拼接字符串函数
    几个常见Win32 API函数
    C 数组模拟阶乘运算
    leetcode 2. Add Two Numbers
    Airline Hub
  • 原文地址:https://www.cnblogs.com/ewitt/p/6648706.html
Copyright © 2020-2023  润新知