存储结构(头尾链)
结构图
代码
typedef enum{ATOM,LIST}ElemTag;//ATOM==0:原子;LIST==1:子表;
typedef struct GLNode {
ElemTag tag;//公共部分,区分原子结点和表结点
union {//原子结点和表结点的联合部分
char atom;//原子结点的值域
struct { struct GLNode* hp, * tp; }ptr;//结点指针域,hp为当前子表头指针
//tp指向当前子表的下一并列子表
};
}*GList;
基本操作
建立广义表
基本项
- 当T为空表,置空广义表
- 当T为单字符串,建立原子结点的子表
归纳项
- 设
sub
为脱去最外层括号的子串,其中sub=S1...Sn
为非空字符串。对每一个Si
建立一个表结点,并令hp
为建立子表的头指针,tp
指针指向在他之后建立的表结点
Status CreatGList(GList& L, HString T) {//创建广义表
HString emp, sub, str;
GList p, q;
PushHString(emp, "()");
//当T为空表串,置空广义表
if (!CompareHString(T, emp)) L = NULL;//创建空表
else {
if (!(L = (GList)malloc(sizeof(GLNode)))) return ERROR;
//当T为单字符串,建立原子结点子表
if (T.length == 1) {
L->tag = ATOM;
L->atom = T.ch[0];
}
//归纳项
else {
L->tag = LIST;p = L;
SubHString(sub, T, 2, T.length - 2);//脱去外层括号
do {
sever(str, sub);//第一次编写为sever(str,T)...一直报错,找了三四个钟头!!!
CreatGList(p->ptr.hp, str);q = p;//hp为建立子表的头指针
if (!EmptHString(sub)) {
p = (GList)malloc(sizeof(GLNode));//tp指向在它之后建立的结点
p->tag = LIST;q->ptr.tp = p;
}
} while (!EmptHString(sub));
q->ptr.tp = NULL;
}
}
return OK;
}
字串分割函数
- 判断分割位置
- 当字串有
,
时 - 当字串没有
,
时
Status sever(HString& S, HString& T) {//将串T分割为‘,’前和‘,’后两部分
int n = T.length;int i = 0;int k = 0;//k为尚未配对的左括号数
//之所以要记录左括号数是因为有子串为原子表,没有‘,’出现
HString ch;
//判断分割位置
do {
i++;
SubHString(ch, T, i, 1);
if (ch.ch[0] == '(') ++k;
else if (ch.ch[0] == ')') --k;
} while (i < n && (ch.ch[0] != ',' || k != 0));//当k为零,即说明已经搜索了一队括号的内容
//也即说明当前串为原子表,没有‘,’
//当字串有“,”
if (i < n) {
SubHString(S, T, 1, i - 1);
SubHString(T, T, i + 1, n - i);
}
//当字串没有“,”
else {
CopyHString(S, T);
ClearHString(T);
}
return OK;
}
求广义表深度
基本项
- 空表深度为1
- 原子表深度为0
归纳项
- 列表深度为各子表最大深度加1
Status DepthGList(GList L) {//求列表深度
if (!L) return 1;//空表深度为1
if (L->tag == 0) return 0;//原子表深度为0
int dep, max ;GList pp;
for (max = 0, pp=L;pp;pp = pp->ptr.tp) {//遍历列表,归纳项为列表深度为各个子表深度最大值加1
dep = DepthGList(pp->ptr.hp);
if (dep > max) max = dep;
}
return max + 1;
}
打印广义表
void PrintGList2(GList L) {
GLNode* p;
if (!L)
{
cout << "()";
}
else
{
if (L->tag == ATOM)
{
cout << L->atom;
}
else
{
p = NULL;
cout << '(';
p = L;
while (p)
{
PrintGList2(p->ptr.hp);
p = p->ptr.tp;
if (p)
{
cout << ',';
}
}
cout << ')';
}
}
}