广义表的实现(法二)

#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
时间: 2024-10-10 17:31:26

广义表的实现(法二)的相关文章

33. 蛤蟆的数据结构笔记之三十三广义表实现二

33. 蛤蟆的数据结构笔记之三十三广义表实现二 本篇名言:" 希望是附丽于存在的,有存在,便有希望,有希望,便是光明.--鲁迅" 我们继续来看下广义表的其他代码实现.代码均来自网络,解释来自蛤蟆,均亲测可行. 欢迎转载,转载请标明出处: 1.  广义表实现二 1.1         main 创建两个链表的指针head和L. 输入一个字符串,调用GLCreate函数创建广义表.显示,获取头表,尾表,输出长度,深度,原子个数,复制列表,Merge列表,遍历,比较广义表操作. 如下图1:

数据结构实践项目——数组和广义表

本文针对 [数据结构基础系列网络课程(5):数组和广义表] 1. 数组的基本概念与存储结构 2. 特殊矩阵的压缩存储 3. 稀疏矩阵的三元组表示 4. 稀疏矩阵的十字链表表示 5. 广义表 6. 广义表的存储结构及基本运算的实现 [项目1 - 猴子选大王(数组版)] 一群猴子,编号是1,2,3 -m,这群猴子(m个)按照1-m的顺序围坐一圈.从第1只开始数,每数到第n个,该猴子就要离开此圈,这样依次下来,最后一只出圈的猴子为大王.输入m和n,输出猴子离开圈子的顺序,从中也可以看出最后为大王是几号

数组和广义表-第5章-《数据结构题集》答案解析-严蔚敏吴伟民版

习题集解析部分 第5章 数组和广义表 ——<数据结构题集>-严蔚敏.吴伟民版        源码使用说明  链接??? <数据结构-C语言版>(严蔚敏,吴伟民版)课本源码+习题集解析使用说明        课本源码合辑  链接??? <数据结构>课本源码合辑        习题集全解析  链接??? <数据结构题集>习题解析合辑       本习题文档的存放目录:数据结构\▼配套习题解析\▼05 数组和广义表       文档中源码的存放目录:数据结构\▼配

数组和广义表

1.数组 数组的特点: 元素数目固定:下标有界. 数组的操作: 按照下标进行读写. 2.数组的顺序表示和实现 因计算机的内存结构是一维的,因此用一维内存来表示多维数组,就必须按某种次序将数组元素排成一列序列,然后将这个线性序列存放在储存器中. 通常有两种顺序存储方式: (1)行优先顺序--将数组元素按行排列 在PASCAL.C语言中,数组就是按行优先顺序储存. (2)列优先顺序--将数组按列向量排列. 在FORTRAN语言中,数组就是按列优先顺序储存的. 3.矩阵的压缩储存 利用2维数组描述矩阵

广义表 (五)

5.1广义表-广义表的定义和基本运算 顾名思义,广义表是线性表的推广.也有人称其为列表(Lists,用复数形式以示与统称的表List 的区别). ⒈广义表的定义和性质 我们知道,线性表是由n 个数据元素组成的有限序列.其中每个组成元素被限定为单元素,有时这种限制需要拓宽.例如,中国举办的某体育项目国际邀请赛,参赛队清单可采用如下的表示形式: (俄罗斯,巴西,(国家,河北,四川),古巴,美国,(),日本) 在这个拓宽了的线性表中,韩国队应排在美国队的后面,但由于某种原因未参加,成为空表.国家队.河

数据结构4(数组和广义表)

第4章  数组和广义表 [例4-1]二维数组A的每一个元素是由6个字符组成的串,其行下标i=0,1,…,8,列下标j=1,2,…,10.若A以行为主序存储元素,A[8][5]的物理地址与当A按列为主序存储时的元素(  )的物理地址相同.设每个字符占一个字节. A.A[8][5]    B.A[3][10]    C.A[5][8]    D.A[0][9] //作图 解:  二维数A是一个9行10列的矩阵,即A[9][10].按行存储时,A[8][5]是第85个元素存储的元素.而按列存储时,第8

数据结构与算法系列研究四——数组和广义表

稀疏矩阵的十字链表实现和转置 一.数组和广义表的定义 数组的定义1:一个 N 维数组是受 N 组线性关系约束的线性表.           二维数组的逻辑结构可形式地描述为:           2_ARRAY(D,R)              其中 D={aij} | i=0,1,...,b1-1; j=0,1,...,b2-1;aij∈D0}              R={Row,Col}              Row={<aij,ai,j+1>|0<=i<=b1-1;

javascript实现数据结构:广义表

原文:javascript实现数据结构:广义表  广义表是线性表的推广.广泛用于人工智能的表处理语言Lisp,把广义表作为基本的数据结构. 广义表一般记作: LS = (a1, a2, ..., an) LS是广义表的名称,n是它的长度,ai可以是单个元素,也可以是广义表,分别称为广义表LS的原子和子表.习惯上,用大写字母表示广义表的名称,小写字母表示原子.当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2, a3, ..., an)是LS的表尾. 下面列举一些广义表的例

第五章:1.数组和广义表 -- 数组

前言: 2.3.4章讨论的线性结构中的数据元素都是非结构的原子类型,元素的值是不再分解的.本章讨论的两种数据结构---数组和广义表可以看成是线性表在下述含以上的扩展:表中的数据元素本身也是一个数据结构. 其中.数组是一种比较熟知的数据类型,几乎所有程序语言都把数组类型设定为固有类型,前两节节以抽象数据类型的形式讨论数组的定义和实现,使读者加深对数组的理解. 目录: 1.数组的定义 2.数组的顺序表示和实现 3.矩阵的压缩存储 4.广义表的定义 5.广义表的存储结构 6.m元多项式的表示 7.广义