广义表存储

来源:互联网 发布:幼儿考级舞蹈软件 编辑:程序博客网 时间:2024/05/31 00:40

节点形态:


存储结构:


每个节点都包含一个标志域,如果为0(即原子),那么仅含一个值域,如果是1(列表),那么说明该节点包含两个指针域。
需要注意的是求广义表长度的操作,其实计算的是根节点及其兄弟的个数,比如图2中广义表的长度为2,图3中广义表的长度为4。



深度的定义方式是递归式的,定义空表深度为1,原子深度为0,广义表的深度比其子表的深度的最大值大1.故图2的深度为3,图3的深度为2。
注意:任何一个非空列表其表头可能是原子,也可能是列表,但是其表尾必定是列表,也就是说不存在这样的广义表:


具体实现:

/************************************广义表存储结构by Rowandjj2014/5/13************************************/#include<iostream>using namespace std;/*广义表的头尾链表存储表示*/typedef enum{ATOM,LIST}ElemTag;//ATOM == 0,原子;LIST == 1,子表typedef int AtomType;typedef struct _BROADLIST_{    ElemTag tag;/*标志域,用于区分是原子节点还是子表*/    union/*原子节点和表节点的联合部分*/    {        AtomType atom;/*原子节点的值域*/        struct/*子表的指针域,ptr.hp和ptr.tp分别指向表头和表尾*/        {            struct _BROADLIST_ *hp,*tp;        }ptr;    }Data;}BroadList,*pBroadList,**ppBroadList;//---------------------------------------------------void InitBroadList(ppBroadList ppBroadListTemp);void DestroyBroadList(ppBroadList ppBroadListTemp);bool CopyBroadList(ppBroadList ppBroadListTemp,pBroadList pBroadListTemp);void TravelBroadList(pBroadList pBroadListTemp);int GetLength(pBroadList pBroadListTemp);//获取广义表长度,其实求的是根节点以及兄弟节点个总个数int GetDepth(pBroadList pBroadListTemp);//求广义表深度pBroadList GetHead(pBroadList pBroadListTemp);//获取头节点pBroadList GetTail(pBroadList pBroadListTemp);//获取表尾bool InsertFirst(ppBroadList ppBroadListTemp,pBroadList pBroadListTemp);//将pBroadListTemp插入广义表首位,该节点可能是原子也可能是表bool DeleteFirst(ppBroadList ppBroadListTemp,ppBroadList pRet);//删除广义表的第一元素,并用pRet返回//---------------------------------------------------void InitBroadList(ppBroadList ppBroadListTemp){    if(ppBroadListTemp != NULL)    {        free(*ppBroadListTemp);    }    *ppBroadListTemp = NULL;}void DestroyBroadList(ppBroadList ppBroadListTemp){    if(*ppBroadListTemp == NULL)    {        return;    }    if((*ppBroadListTemp)->tag == ATOM)//原子类型    {        free(*ppBroadListTemp);        *ppBroadListTemp = NULL;    }    else    {        pBroadList pChild = NULL;        pBroadList pBrother = NULL;        pChild = (*ppBroadListTemp)->Data.ptr.hp;        pBrother = (*ppBroadListTemp)->Data.ptr.tp;        free(*ppBroadListTemp);        //递归调用        DestroyBroadList(&pChild);        DestroyBroadList(&pBrother);    }}bool CopyBroadList(ppBroadList ppBroadListTemp,pBroadList pBroadListTemp){    if(pBroadListTemp == NULL)    {        *ppBroadListTemp = NULL;        return false;    }    *ppBroadListTemp = (pBroadList)malloc(sizeof(BroadList));//动态创建新节点    memset(*ppBroadListTemp,0,sizeof(BroadList));//初始化内存    if(*ppBroadListTemp == NULL)    {        return false;    }    (*ppBroadListTemp)->tag = pBroadListTemp->tag;//复制标志位    if(pBroadListTemp->tag == ATOM)    {        (*ppBroadListTemp)->Data.atom = pBroadListTemp->Data.atom;//复制原子节点数据值        return true;    }    else//递归调用自己    {            CopyBroadList(&((*ppBroadListTemp)->Data.ptr.hp),pBroadListTemp->Data.ptr.hp);        CopyBroadList(&((*ppBroadListTemp)->Data.ptr.tp),pBroadListTemp->Data.ptr.tp);    }    return true;}void TravelBroadList(pBroadList pBroadListTemp)//遍历{    if(pBroadListTemp == NULL)    {        return;    }    if(pBroadListTemp->tag == ATOM)    {        cout<<pBroadListTemp->Data.atom<<" ";    }    else    {        TravelBroadList(pBroadListTemp->Data.ptr.hp);        TravelBroadList(pBroadListTemp->Data.ptr.tp);    }}int GetLength(pBroadList pBroadListTemp){    if(pBroadListTemp == NULL)    {        return 0;    }    int len = 0;    if(pBroadListTemp->tag == ATOM)    {        return 1;    }    pBroadList pTravel = pBroadListTemp;    while(pTravel != NULL)    {        len++;        pTravel = pTravel->Data.ptr.tp;        }    return len;}int GetDepth(pBroadList pBroadListTemp){    if(pBroadListTemp == NULL)//空表的深度为1    {        return 1;    }    if(pBroadListTemp->tag == ATOM)//原子深度为0    {        return 0;    }    pBroadList pTemp = pBroadListTemp;    int max = 0,depth;    for(;pTemp!=NULL; pTemp = pTemp->Data.ptr.tp)//横向扫描    {        depth = GetDepth(pTemp->Data.ptr.hp);        if(depth>max)        {            max = depth;        }    }    return max+1;/*非空表的深度是各元素的深度的最大值加1*/}pBroadList GetHead(pBroadList pBroadListTemp){    /*仅仅获取头节点,并不包括头节点的兄弟节点,但是却包括头节点的孩子节点(如果有的话)*/    if(pBroadListTemp == NULL)    {        exit(0);    }    pBroadList h,p;    h = pBroadListTemp->Data.ptr.tp;    pBroadListTemp->Data.ptr.tp = NULL;//截断    CopyBroadList(&p,pBroadListTemp);    pBroadListTemp->Data.ptr.tp = h;//重新接回去    return p;}pBroadList GetTail(pBroadList pBroadListTemp){    pBroadList pTemp;    if(pBroadListTemp == NULL)    {        exit(0);    }    CopyBroadList(&pTemp,pBroadListTemp->Data.ptr.tp);    return pTemp;}bool InsertFirst(ppBroadList ppBroadListTemp,pBroadList pBroadListTemp){    //算法比较有趣,直接创建一个新的表,表头指针指向新节点,表尾指向旧表    pBroadList pNew = (pBroadList)malloc(sizeof(BroadList));    if(pNew == NULL)    {        return false;    }    memset(pNew,0,sizeof(BroadList));    pNew->tag = LIST;    pNew->Data.ptr.hp = pBroadListTemp;    pNew->Data.ptr.tp = *ppBroadListTemp;    *ppBroadListTemp = pNew;    return true;}bool DeleteFirst(ppBroadList ppBroadListTemp,ppBroadList pRet){    if(*ppBroadListTemp == NULL)    {        return false;    }    pBroadList pTemp;    *pRet = (*ppBroadListTemp)->Data.ptr.hp;    pTemp = *ppBroadListTemp;    *ppBroadListTemp = (*ppBroadListTemp)->Data.ptr.tp;    free(pTemp);    return true;}

部分测试代码:

int main(){    pBroadList pBroadListTemp = (pBroadList)malloc(sizeof(BroadList));    //记得初始化,不然很讨厌..    memset(pBroadListTemp,0,sizeof(BroadList));    pBroadListTemp->tag = LIST;        pBroadListTemp->Data.ptr.hp = (pBroadList)malloc(sizeof(BroadList));    memset(pBroadListTemp->Data.ptr.hp,0,sizeof(BroadList));    pBroadListTemp->Data.ptr.hp->tag = ATOM;    pBroadListTemp->Data.ptr.hp->Data.atom = 1;    pBroadListTemp->Data.ptr.tp = (pBroadList)malloc(sizeof(BroadList));    memset(pBroadListTemp->Data.ptr.tp,0,sizeof(BroadList));    pBroadListTemp->Data.ptr.tp->tag = LIST;    pBroadListTemp->Data.ptr.tp->Data.ptr.tp = NULL;    pBroadListTemp->Data.ptr.tp->Data.ptr.hp = (pBroadList)malloc(sizeof(BroadList));    memset(pBroadListTemp->Data.ptr.tp->Data.ptr.hp,0,sizeof(BroadList));    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->tag = LIST;    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.hp = (pBroadList)malloc(sizeof(BroadList));    memset(pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.hp,0,sizeof(BroadList));    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.hp->tag = ATOM;    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.hp->Data.atom = 2;        pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp = (pBroadList)malloc(sizeof(BroadList));    memset(pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp,0,sizeof(BroadList));        pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp->tag = LIST;    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp->Data.ptr.tp = NULL;    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp->Data.ptr.hp = (pBroadList)malloc(sizeof(BroadList));    memset(pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp->Data.ptr.hp,0,sizeof(BroadList));    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp->Data.ptr.hp->tag = ATOM;    pBroadListTemp->Data.ptr.tp->Data.ptr.hp->Data.ptr.tp->Data.ptr.hp->Data.atom = 3;    pBroadList p;    CopyBroadList(&p,pBroadListTemp);        TravelBroadList(p);    cout<<"\n------------------"<<endl;    cout<<"depth = "<<GetDepth(pBroadListTemp)<<endl;    TravelBroadList(pBroadListTemp);    cout<<endl;    cout<<"len = "<<GetLength(pBroadListTemp)<<endl;    cout<<"copy,len = "<<GetLength(p)<<endl;    cout<<"------------------------"<<endl;    cout<<"depth = "<<GetDepth(pBroadListTemp)<<endl;    cout<<"copy,depth = "<<GetDepth(p)<<endl;       cout<<"--------------"<<endl;    pBroadList temp = GetHead(pBroadListTemp->Data.ptr.tp);    TravelBroadList(temp);    cout<<"\n--------------"<<endl;    TravelBroadList(GetTail(pBroadListTemp));    cout<<"\n--------------"<<endl;        DestroyBroadList(&pBroadListTemp);    DestroyBroadList(&p);    return 0;}



1 0