最近在學習數據結構,用的教材是嚴老師的《數據結構》(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;
}
以上只是我的理解, 如有不對的地方,請多多給指教!