//Header.h
#ifndef HEADER_H
#define HEADER_H
// 预定义常量和类型
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
#endif
/***********************************************/
//GList.h
#ifndef GLIST_H
#define GLIST_H
#include <iostream>
#include "Header.h"
using namespace std;
typedef char AtomType;
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; /* ptr是表节点的指针域,ptr.hp和ptr.tp分别指向表头和表尾 */
};
} *GList, GLNode; /* 广义表类型 */
/* 广义表的头尾链表存储的基本操作(11个) */
void InitGList(GList &L);
void CreateGList(GList &L, string S);
void DestroyGList(GList &L);
void CopyGList(GList &T, GList L);
int GListLength(GList L);
int GListDepth(GList L);
Status GListEmpty(GList L);
GList GetHead(GList L);
GList GetTail(GList L);
void InsertFirst_GL(GList &L, GList e);
void DeleteFirst_GL(GList &L, GList &e);
void Traverse_GL(GList L, void (*visit)(AtomType));
void Sever(string &sub, string &hsub);
void Visit(AtomType e);
#endif
/*****************************************************************/
//GList.cpp
/* 广义表的头尾链表存储表示 */
#include <cstdlib>
#include "GList.h"
using namespace std;
/* 创建空的广义表L */
void InitGList(GList &L)
{
L = NULL;
}
/* 采用头尾链表存储结构,由广义表的书写形式串S创建广义表L。设emp="()" */
void CreateGList(GList &L, string S)
{
string sub, hsub, emp("()");
GList p, q;
if (S == emp)
L = NULL; /* 创建空表 */
else { /* S不是空串 */
L = (GList)malloc(sizeof(GLNode));
if (!L)
exit(OVERFLOW);
if (S.length() == 1) { /* S为单原子,只会出现在递归调用中 */
L->tag = ATOM;
L->atom = S[0]; /* 创建单原子广义表 */
} else { /* S为表 */
L->tag = LIST;
p = L;
sub = S.substr(1, S.length() - 2); /* 脱外层括号(去掉第一个字符和最后一个字符)给串sub */
do { /* 重复建n个子表 */
Sever(sub, hsub); /* 从sub中分离出表头串hsub */
CreateGList(p->ptr.hp, hsub);
q = p;
if(!sub.empty()) { /* 表尾不空 */
p = (GLNode *)malloc(sizeof(GLNode));
if (!p)
exit(OVERFLOW);
p->tag = LIST;
q->ptr.tp = p;
}
} while (!sub.empty());
q->ptr.tp = NULL;
}
}
}
//销毁广义表
void DestroyGList(GList &L)
{
GList q1, q2;
if (L) {
if (L->tag == LIST) { // 删除表节点
q1 = L->ptr.hp; // q1指向表头
q2 = L->ptr.tp; // q2指向表尾
DestroyGList(q1); //销毁表头
DestroyGList(q2); //销毁表尾
}
free(L);
L = NULL;
}
}
// 采用头尾链表存储结构,由广义表L复制得到广义表T
void CopyGList(GList &T, GList L)
{
if (!L) //复制空表
T = NULL;
else {
T = (GList)malloc(sizeof(GLNode)); // 建表节点
if (!T)
exit(OVERFLOW);
T->tag = L->tag;
if (L->tag == ATOM)
T->atom = L->atom; // 复制单原子
else {
CopyGList(T->ptr.hp, L->ptr.hp);
CopyGList(T->ptr.tp, L->ptr.tp);
}
}
}
// 返回广义表的长度
int GListLength(GList L)
{
int len = 0;
while (L) {
L = L->ptr.tp;
++len;
}
return len;
}
// 采用头尾链表存储结构,求广义表L的深度
int GListDepth(GList L)
{
int max, dep;
GList pp;
if (!L)
return 1; // 空表深度为1
if (L->tag == ATOM)
return 0; // 原子深度为0,只会出现在递归调用中
for (max = 0, pp = L; pp; pp = pp->ptr.tp) {
dep = GListDepth(pp->ptr.hp); // 递归求以pp->ptr.hp为头指针的子表深度
if (dep > max)
max = dep;
}
return max + 1; // 非空表的深度是各元素的深度的最大值加1
}
// 判定广义表是否为空
Status GListEmpty(GList L)
{
if (!L)
return TRUE;
else
return FALSE;
}
// 生成广义表L的表头元素,返回指向这个元素的指针
GList GetHead(GList L)
{
GList h, p;
if (!L) // 空表无表头
return NULL;
p = L->ptr.hp; // p指向L的表头元素
CopyGList(h, p); // 将表头元素复制给h
return h;
}
// 将广义表L的表尾生成为广义表,返回指向这个新广义表的指针
GList GetTail(GList L)
{
GList t;
if (!L) // 空表无表尾
return NULL;
CopyGList(t, L->ptr.tp); // 将L的表尾复制给t
return t;
}
// 初始条件:广义表存在
//操作结果:插入元素e(也可能是子表)作为广义表L的第一个元素(表头)
void InsertFirst_GL(GList &L, GList e)
{
GList p = (GList)malloc(sizeof(GLNode)); // 生成新节点
if (!p)
exit(OVERFLOW);
p->tag = LIST; // 节点的类型是表
p->ptr.hp = e; // 表头指向e
p->ptr.tp = L; // 表尾指向原表
L = p; // L指向新节点
}
// 初始条件:广义表L存在
// 操作结果:删除广义表L的第一个元素,并用e返回其值
void DeleteFirst_GL(GList &L, GList &e)
{
GList p = L; // p指向第一个节点
e = L->ptr.hp; // e指向L的表头
L = L->ptr.tp; // L指向原L的表尾
free(p); // 释放第一个节点
}
// 利用递归算法遍历广义表L
void Traverse_GL(GList L, void (*visit)(AtomType))
{
if (L) { // 不空
if (L->tag == ATOM) // L为单原子
visit(L->atom);
else { // L为广义表
Traverse_GL(L->ptr.hp, visit); // 递归遍历L的表头
Traverse_GL(L->ptr.tp, visit); // 递归遍历L的表头
}
}
}
void Visit(AtomType e)
{
cout << e << " ";
}
void Sever(string &sub, string &hsub)
{
int n = sub.length(), i = 0, k = 0;
char ch;
do {
ch = sub[i];
switch (ch) {
case '(': ++k; break;
case ')': --k; break;
}
++i;
} while (i <= n && (ch != ',' || k != 0));
if (i <= n) {
hsub = sub.substr(0, i - 1); //!
sub = sub.substr(i, n - i + 1);
} else {
hsub = sub;
sub.clear();
}
}
/*****************************************************/
//main.cpp
#include "GList.h"
using namespace std;
void process(string s);
int main()
{
string s;
string s1("()");
string s2("((A),((B),C),D)");
string s3("((A,(B,(C))),(),(((((D),E)))))");
string s4("(A,(B),(),((C)),D)");
string s5("((),A,(B))");
string s6("(((A,(B)),C,(D),((E)),F))");
process(s1);
process(s2);
process(s3);
process(s4);
process(s5);
process(s6);
return 0;
}
void process(string s)
{
GList L;
CreateGList(L, s);
int len, dep;
len = GListLength(L);
dep = GListDepth(L);
cout << "len=" << len << "/tdep=" << dep << "/t";
Traverse_GL(L, Visit);
cout << endl;
}
/*********************************************/