广义表1——基本内容

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36669549/article/details/85109153

广义表

与数组一样,广义表也是线性表的推广。它是一种递归定义的数据结构,但其数据元素的结构类型可以不同,其元素可以是普通元素,也可以是广义表。广义表被广泛应用于人工智能等领域的表处理语言Lisp中它把广义表作为基本的数据结构,就连程序也表示成一系列的广义表。

【广义表的定义及头尾链表表示】
广义表,简称表(lists),是由n个元素(a1,a2,a3,…,an)组成的有限序列。当n=0时称为空表。在一个非空的广义表中,其元素ai可以是某一确定类型的对象(这种元素被称为单元素或原子),也可以是由原子构成的表(这种元素被称为子表或表元素)。显然,广义表的定义是递归的。广义表记作(a1,a2,a3,.... ,an)。其中,GL是广义表的名字,n是广义表的长度。在广义表GL中,a1称为广义表GL的表头(head),其余元素组成的表(a2,a3,...,an)称为表尾(tail)。

例如:
(1)A=0,广义表A是长度为0的空表。
(2)B=(a),B是一个长度为1且元素为原子的广义表(其实就是前面讨论过的一般的线性表)。
(3)C=(a,(b,c)),C是长度为2的广义表。其中,第1个元素是原子a,第2 个元素是一个子表(b,c)。
(4)D=(A,B,C),D 是一个长度为3的广义,这3个元素都是子表,第1个元素是一个空表A。
(5)E=(a,E),E是一个长度2的递归广义表,相当于E=(a,(a,(a,(a,(a, ...)))))。任何一个非空广义表的表头可以是一个原子,也可以是一个广义表,而表尾一定是一个广义表。例如:

L=(a,(b,(c,(d)), e), f )
⑴ L1=Tail(L)=((b,(c,(d)), e), f )
⑵ L2=Head(L1)= (b,(c,(d)), e)

⑶ L3=Tail(L2)=((c,(d)), e)

⑷ L4=Head(L3)=(c,(d))

⑸ L5=Head(L4)= c

习惯上,广义表的名字用大写字母表示,原子用小写字母表示。

【性质】
(1)有次序性。广义表中的元素有固定的相对次序。从某种程度上,广义表是线性排列的,可以把广义表看成是线性表的推广。同时,它又是层次结构,可以把它看成树的推广。
(2)有长度。广义表的长度定义为最外层括弧中包含的数据元素的个数。表中的元素个数是有限的,也可以是空表。
(3)有深度。广义表的深度定义为括弧的最大重数,空表的深度为1。
(4)可递归。
(5)可共享。即子表可被多个广义表共享。
【存储结构】
由于广义表中的元素可以是原子,也可以是广义表,显然难以用顺序存储结构表示。广义表中有两种元素:原子和子表,因此需要两种结构的结点:一种是原子结点,用来表示原子;另一种是表结点,用来表示表元素。一般用链式方式表示广义表,有两种存储方式:头尾链表存储结构和扩展线性链表存储结构。

其中头尾链表存储结构由两种结点构成:原子结点和表结点。其中,表结点包含3个域:标志域,指向表头的指针域和指向表尾的指针域。原子结点包含两个域:标志域和值域。表结点和原子结点原子结点的存储结构

如图所示。

其中,tag=1是子表,hp和tp分别指向表头结点和表尾结点,tag=0表示原子,atom用于存储原子的值。

用头尾链法表示广义表A=(),B=(a),C=(a,(b,c)),D=(A,B,C),E=(a,E)

广义表的头尾链表存储结构类型描述如下:

typedef enum{ATOM,LIST}ElemTag; /*ATOM=0,表示原子,LIST=1,表示子表*/
typedef struct
{
    ElemTag tag;                 /*标志位tag用于区分元素是原子还是子表*/
    union
    {
        AtomType atom;         /*AtomType是原子结点的值域,用户自己定义类型*/
        struct
        {
            struct GLNode *hp,*tp;        /*hp指向表头,tp指向表尾*/
        }ptr;
    };
}*GList,GLNode;


 

猜你喜欢

转载自blog.csdn.net/baidu_36669549/article/details/85109153
今日推荐