最近在学习数据结构,用的教材是严老师的《数据结构》(C语言版),学习到广义表这节时,遇到点疑问,查资料无果,故写此博客,望大神们多多指教!
废话少说,在广义表一般记作LS = (a1, a2, ...,an),ai(1 <= i <= n)可以是单个元素,也可以是广义表。当广义表LS非空时,称第一个元素a1为LS的表头,称其余元素组成的表(a2, a3, ..., an)是LS的表尾。由定义可知,非空广义表LS的表尾一定还是广义表。分别定义两个函数,GetHead(L)为取表头函数,GetTail(L)为取表尾函数,例如:
L = (a, (b , c, d)),则GetHead(L) = a,GetTail(L) = ((b, c, d)).
假如广义表的存储方式定义如下:
typedef enum {ATOM, LIST} ElemTag; //ATOM==0:原子,LIST==1:子表
typedef struct GLNode
{
ElemTag tag; //公共部分,用于区分原子结点和表结点
union
{
AtomType atom; //atom是原子结点的值域,AtomType由用户定义
struct
{
struct GLNode *hp, *tp; //ptr.hp和ptr.tp分别指向表头和表尾
}ptr;
};
}*GList;
下面是GetHead(L)与GetTail(L)的实现代码:
GList GetHead(GList L)
{
if(NULL == L) return NULL;
if(ATOM == L->tag) return L;
return L->ptr.hp;
}
GList GetTail(GList L)
{
if(NULL == L || ATOM == L->tag) return NULL;
return L->ptr.tp;
}
取表头函数没有什么疑问,在取表尾函数中,直接返回指向表尾的指针,如果是这样实现,则在上面的例子中GetTail(L) = (b, c, d),这与定义不符合,查了很多资料上的实现,实现的思路基本都是这样。如果只是为了实现起来比较容易,在用的时候就需要注意了,例如,在求广义表深度时,把广义表分解成表头和表尾两个部分,如下:
int GListDepth(GList L)
{
int dep1, dep2;
if(NULL == L) return 1;
if(ATOM == L->tag) return 0;
dep1 = GListDepth(GetHead(L)) + 1;
dep2 = GListDepth(GetTail(L)) + 1; //由于实现原因,这里也需要加1
return dep1 > dep2 ? dep1 : dep2;
}
以上只是我的理解, 如有不对的地方,请多多给指教!