广义表(GeneralList)的c++类实现

 #define HEAD 0  //表头结点类型
#define INTGR 1  //整数类型
#define CH 2  //字符类型
#define LST 3 //子表类型

class Genlist;//GenList类的前视声明
class GenListNode{
    
    //友元类声明,作用:GenList类的所有成员函数均可访问GenListNode类的私有成员
    friend class GenList;
private:
    int utype;//结点类型 =0/1/2/3 ,分别表示:HEAD/INTGR/CH/LST
    
    GenListNode * tlink;//同一层下个结点的指针
    
    union{
        int ref;//HEAD:表头结点情形 表示引用计数
        int intgrinfo;//INTGR:存放整数值
        char charinfo;//存放字符
        GenListNode* hlink;//存放指向子表的指针
    }value;
public:
    GenListNode &Info(GenListNode *elem);//返回表元素elem的值
    int nodetype(GenListNode* elem){return elem->utype;}//返回表元素elem的元素值的数据类型
    void setInfo(GenListNode * elem,GenListNode &x);//将elem元素值修改为x
};
class GenList{
    //私有函数
    GenListNode * first;//广义表头指针
    
    GenListNode * Copy(GenListNode * ls);//复制一个ls指示的无共享子表的非递归表

    int depth(GenListNode *ls);//计算由ls指示的非递归表的深度

    int equal(GenListNode *s,GenListNode *t);//比较分别以s和t为表头结点的广义表是否相同
    
    void Remove(GenListNode *ls);//将以ls为表头结点的广义表释放

public:

    GenList();//构造函数
    ~GenList();//析构函数

    GenListNode& Head();//返回表头
    GenListNode& Tail();//返回表尾
    GenListNode * First();//返回广义表第一个元素
    GenListNode * Next(GenListNode *elem);//返回表元素elem的直接后继元素
    
    //公开的操作方法
    void Push(GenListNode & x);//将一个包含值x的元素加入到广义表的最前端
    GenList& Addon(GenList &list,GenListNode &x);//返回一个新的广义表,表头为x,表尾为list

    void setHead(GenListNode &x);//将广义表的头元素重置为x

    void SetNext(GenListNode *elem1,GenListNode *elem2);//将elem2插入到elem1后面
    void SetTail(GenList& list);//将list定义为广义表的表尾
    void Copy(const GenList &l);//广义表复制
    int depth();//计算广义表的深度

    //创建表
    int CreateList(GenListNode * ls,char *s);
    //从广义表的字符串描述s出发,建立一个带表头结点的广义表结构

};

//类实现
/

GenListNode& GenListNode::Info(GenListNode *elem)
{
    GenListNode * pitem=new GenListNode;
    pitem->utype=elem->utype;
    pitem->value=elem->value;
    return *pitem;
}

void GenListNode::setInfo(GenListNode *elem,GenListNode &x){
    elem->utype=x->utype;
    elem->value=x->value;
}


//广义表类的构造函数和析构函数
GenList::GenList()
{
    //建立表头结点
    GenListNode *first=new GenListNode;
    first->utype=0;
    first->ref=1;
    first->tlink=NULL;
}

GenListNode& GenList::Head()
{
//若广义表非空,则返回其第一个元素的值否则函数没有定义
    if(first->tlink==NULL)
    {
        cout<<"Illegal head operation"<<endl;exit(1);
    }
    else
    {
        GenListNode *temp=new GenListNode;
        temp->utype=first->tlink->utype;
        temp->value=first->tlink->value;
        return *temp;//返回类型及值
    }
}

GenListNode * GenList::Tail()
{
    //若广义表非空,则返回除第一元素以外的其他元素组成的表,否则函数没有定义
    if(first->tlink==NULL)
    {
        cout<<"Illegal tail operation"<<endl;exit(1);

    }
    else
    {
        GenList *temp;//复制,第一个元素结点作为表头结点
        temp->first->tlink=Copy(first->tlink->tlink);
        return temp;
    }
}

//返回广义表的第一个元素
GenListNode *GenList::First()
{
    if(first->tlink==NULL)return null;
    else
        return first->tlink;
}
//返回后继元素
GenListNode * GenList::Next(GenListNode *elem)
{
if(elem->tlink==NULL)return null;
else return elem->tlink;
}


void GenList::Push(GenListNode &x)
{
    if(first->tlink==NULL) first->tlink=x;
    else
    {
        x->tlink=first->tlink->tlink;
        first->tlink=x;
    }
}


GenList & GenList::Addon(GenList &list,GenListNode&x)
{
    GenList * newlist=new GenList;
    newlist->first=Copy(list.first);
    x->tlink=newlist->first->tlink;
    newlist->first->tlink=x;
    return * newlist;
}

//将第一个元素结点置为x
void GenList::setHead(GenListNode &x)
{
    first->tlink->utype=x->utype;
    first->tlink->value=x->value;
}

void GenList::SetNext(GenListNode *elem1,GenListNode *elem2)
{
    //要求elem1不能为空元素
    GenListNode * temp;
    while(elem1->tlink!=NULL)
    {
        temp->elem1->tlink;
        elem1->tlink=temp->tlink;
        delete temp;
    }
    elem1->tlink=elem2;//连接
}

void GenList::SetTail(GenList &list)
{
    GenListNode *temp;
    temp=first->tlink->tlink;
    first->tlink->tlink=list.first->tlink;
    delete list.first;//删除list表头结点
    freelist(temp);//释放原来的表尾
}


//递归算法

//公共函数
void GenList::Copy(const GenList &l)
{
    first=Copy(l.first);
}
//私有函数
GenListNode * GenList::Copy(GenListNode *ls)
{
    GenListNode *q=NULL;
    if(ls!=NULL)
    {

        q=new GenListNode;
        q->utype=ls->utype;
        switch(ls->utype)
        {
            case HEAD:
                q->value.ref=ls->value.ref;
                break;
            case INTGR:
                q->value.intgrinfo=ls->value.intgrinfo;
                break;
            case CH:
                q->value.charinfo=ls->value.charinfo;
                break;
            case LST:
                q->value.hlink=Copy(ls->value.hlink);
                break;
        }
        q->tlink=Copy(ls->tlink);
    }
    return q;
}




//求广义表的深度
int GenList::depth()
{
    return depth(first);
}

int GenList::depth(GenListNode *ls)
{
    if(ls->tlink==NULL)return 1;
    GenListNode *temp=ls->tlink;
    int m=0;
    while(temp!=NULL)
    {
        if(temp->utype==LST)
        {
            int n=depth(temp->value.hlink);
            if(m<n) m=n;
        }
        temp=temp->tlink;
    }
    return m+1;
}

int operator ==(const GenList &l,const GenList &m)
{
    return equal(l.first,m.first);
}

int equal(GenListNode *s,GenListNode *t)
{
    int x;
    if(s->tlink==NULL&&t->tlink==NULL)return 1;

    //以下只计算相等时候的情形
    if(s->tlink!=NULL && t->tlink!=NULL&&s->tlink->utype==t->tlink->utype)
    {
        if(s->tlink->utype==INTGR)
        {
            if(s->tlink->value.intgrinfo==t->tlink->value.intgrinfo)
                x=1;
            else
                x=0;
            
        }else if(s->tlink->utype==CH)
        {
            if(s->tlink->value.charinfo==t->tlink->value.charinfo)
                x=1;
            else
                x=0;
        }else
        {
            x=equal(s->tlink->value.hlink,t->tlink->value.hlink);
        }
        if (x) return equal(s->tlink,t->tlink);
    
    }
    
    return 0;
}


//广义表的删除算法

void delvalue(GenListNode *ls,const value x)
{
    if(ls->tlink!=NULL)
    {
        //非空表
        GenListNode *p=ls->tlink;
        while(p!=NULL&&((p->utype==INTGR&&p->value.intgrinfo==x)||(p->utype==CH)&&p->value.charinfo==x))
        {
            ls->tlink=p->tlink;
            delete p;
            p=ls->tlink;
        }
        if(p!=NULL)
        {
            if(p->utype==LST)//递归调用子表的删除算法
                delvalue(p->value.hlink,x);
            delvalue(p,x);
        }

    }
}


//析构函数:删除共享表中的结点
GenList::~GenList()
{
    Remove(first);
}

void GenList::Remove(GenListNode *ls)
{
    ls->value.ref--;
    if(!ls->value.ref)
    {
        //自己当表头结点的引用计数减到0的时候才可以真正的删除释放
        GenListNode *y=ls;
        while(y->tlink!=NULL)
        {
            y=y->tlink;
            if(y->utype==LST)
                Remove(y->value.hlink);//递归删除子表
                
        }

        //将来ls到最后循环得到的y->tlink中间的一段纳入可利用空间表中
        y->tlink=av;
        av=ls;


    }
}


//☆☆☆☆☆☆☆☆☆☆☆☆☆核心函数☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆

int GenList::CreateList(GenListNode *ls,char *s)
{
    //从广义表的字符串描述s出发,建立一个带表头结点的广义表结构

    char *sub,*hsub,int tag;

    ls=new GenListNode();
    
    ls->utype=HEAD;
    ls->ref=1;
    if(strlen(s)==0||!strcmp(s,'()'))
    ls->tlink=NULL;    //空表
    else
    {
        strncpy(sub,s+1,strlen(s)-2);
        //若带表名(一个字符的),应改为strncpy(sub,s+2,strlen(s)-3)
        GenListNode *p=ls;
        while(strlen(sub)!=0)
        {
            p=p->tlink=new GenListNode();
            if(sever(sub,hsub))
            {
                if(hsub[0]!='('&&hsub[0]!=''')
                {
                    //整型
                    p->utype=INTGR;
                    p->value.intgrinfo=atoi(hsub);
                }else if(hsub[0]!='(' && hsub[0]==''')
                {
                    //字符型
                    p->utype=CH;
                    p->value.charinfo=hsub[1];
                }else
                {
                    p->utype=LST;
                    CreateList(p->value.hlink,hsub);
                }

            }else
            {
                    return 0;
            }
        }
        p->tlink=NULL;//最后结点链域封闭
    }
return 1;

}



//内核函数的辅助算法

int GenList::sever(char *str1,char *str2)
{
    char ch=str1[0];
    int n=strlen(str1);
    int i=0,k=0;

    //取出来的i位置包含","符号
    while(i<n&&(ch!=','||k!=0))
    {
        if(ch=='(')k++;
        else if(ch==')')k--;
        i++;
        ch=str1[i];//取串中字符
    }

    if(i<n)
    {
        strncpy(str2,str1,i-1);
        strncpy(str1,str1+i,n-i);
        return 1;
    }
    else if(k!=0)return 0;
    else
    {
        strcpy(str2,str1);str1=0;
        return 1;
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值