- 广义表的中数据元素可以是原子,也可以是列表。
- 由于元素可以是原子也可以是列表,因此有两种结点类型。
因此用顺序存储表示不方便,通常采用链式存储结构,一个结点表示一个元素。
1、原子节点:标志域和值域
2、表结点:标志域,指示表头的指针域,指示表尾的指针域。
表头表尾法,每一个表都看做表头加上表尾。
把任何一个广义表、表结点都分解成表头表尾结构
typedef enum
{
ATOM, // 0,表示原子
LIST // 1,表示子表
}ElemTag;
typedef struct GLNode
{
ElemTag tag; //公共部分,用于区分原子节点和表结点
union //根据 tag 二选一
{ //要么是原子节点的值域,要么是表结点的头尾节点指针域
AtomType atom;
struct { struct GLNode *hp, *tp } ptr;
};
} *GList //广义表类型
1、A = ( )
空表,表长为0
2、B = (e )
只有1个原子元素,表长为1
3、C = (a, (b, c, d))
有2个元素,分别为原子a 和 子表 (b, c, d)。表长为2
4、D = (A, B, C)
有3个元素都是列表,等价于( (), (e), (a, (b, c, d)) )。表长为3
5、E = (a, E)
递归的表,表长为2。列表可以是本身的一个子表。
( 表尾一定是列表,因此 tag 必为 1,相当于除去表头再套一层括号 )
- 广义表的另一种存储结构(链表法)
把广义表看成是包含 n个并列子表(原子也视为子表)的表
typedef enum
{
ATOM, // 0,表示原子
LIST // 1,表示列表
} ElemTag;
typedef struct GLNode
{
ElemType tag; // 公共部分,用于区分原子结点和表结点
union
{
AtomType atom; // 原子结点的值域
struct GLNode *hp; // 表结点的表头指针
};
struct GLNode *tp; //相当于与线性链表的next,指向下一个结点
} *GList;
1、A = ( )
空表,表长为0
2、B = (e )
只有1个原子元素,表长为1
3、C = (a, (b, c, d))
有2个元素,分别为原子a 和 子表 (b, c, d)。表长为2
4、D = (A, B, C)
有3个元素都是列表,等价于( (), (e), (a, (b, c, d)) )。表长为3
5、E = (a, E)
递归的表,表长为2。列表可以是本身的一个子表。