节点形态:
存储结构:
每个节点都包含一个标志域,如果为0(即原子),那么仅含一个值域,如果是1(列表),那么说明该节点包含两个指针域。
需要注意的是求广义表长度的操作,其实计算的是根节点及其兄弟的个数,比如图2中广义表的长度为2,图3中广义表的长度为4。
深度的定义方式是递归式的,定义空表深度为1,原子深度为0,广义表的深度比其子表的深度的最大值大1.故图2的深度为3,图3的深度为2。
注意:任何一个非空列表其表头可能是原子,也可能是列表,但是其表尾必定是列表,也就是说不存在这样的广义表:
具体实现:
/************************************
广义表存储结构
by Rowandjj
2014/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;
}