赞
踩
下图是根据上方程序定义的广义表(a,(b,c,d))的存储结构。它的长度为 2,第 1 个元素为原子 a,第 2 个元素为子表(b,c,d)。
完整代码:
下面代码中广义表的书写形式串为HString类型,广义表的书写形式串为SString类型的请转看:https://blog.csdn.net/qq_42185999/article/details/105670079
- typedef int Status; /* Status是函数的类型,其值是函数结果状态代码,如OK等 */
- typedef int Boolean; /* Boolean是布尔类型,其值是TRUE或FALSE */
-
- #include<malloc.h> /* malloc()等 */
- #include<stdio.h> /* EOF(=^Z或F6),NULL */
- #include<process.h> /* exit() */
- #include<limits.h> //常量INT_MAX和INT_MIN分别表示最大、最小整数
-
- /* 函数结果状态代码 */
- #define TRUE 1
- #define FALSE 0
- #define OK 1
- #define ERROR 0
- #define INFEASIBLE -1
- #define OVERFLOW -2
-
- 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是表结点的指针域,prt.hp和ptr.tp分别指向表头和表尾 */
- }a;
- }*GList, GLNode; /* 广义表类型 */
-
- /* ---------------------------------------------------------------------------------------------*/
-
-
-
-
- /* --------------------------- 广义表的头尾链表存储的基本操作(11个) --------------------------*/
-
- Status InitGList(GList *L)
- { /* 创建空的广义表L */
- *L = NULL;
- return OK;
- }
-
- void DestroyGList(GList *L) /* 广义表的头尾链表存储的销毁操作 */
- { /* 销毁广义表L */
- GList q1, q2;
- if (*L)
- {
- if ((*L)->tag == ATOM)
- {
- free(*L); /* 删除原子结点 */
- *L = NULL;
- }
- else /* 删除表结点 */
- {
- q1 = (*L)->a.ptr.hp;
- q2 = (*L)->a.ptr.tp;
- free(*L);
- *L = NULL;
- DestroyGList(&q1);
- DestroyGList(&q2);
- }
- }
- }
-
- Status CopyGList(GList *T, GList L)
- { /* 采用头尾链表存储结构,由广义表L复制得到广义表T。算法5.6 */
- if (!L) /* 复制空表 */
- *T = NULL;
- else
- {
- *T = (GList)malloc(sizeof(GLNode)); /* 建表结点 */
- if (!*T)
- exit(OVERFLOW);
- (*T)->tag = L->tag;
- if (L->tag == ATOM)
- (*T)->a.atom = L->a.atom; /* 复制单原子 */
- else
- {
- CopyGList(&((*T)->a.ptr.hp), L->a.ptr.hp);
- /* 复制广义表L->ptr.hp的一个副本T->ptr.hp */
- CopyGList(&((*T)->a.ptr.tp), L->a.ptr.tp);
- /* 复制广义表L->ptr.tp的一个副本T->ptr.tp */
- }
- }
- return OK;
- }
-
- int GListLength(GList L)
- { /* 返回广义表的长度,即元素个数 */
- int len = 0;
- if (!L)
- return 0;
- if (L->tag == ATOM)
- return 1;
- while (L)
- {
- L = L->a.ptr.tp;
- len++;
- }
- return len;
- }
-
- int GListDepth(GList L)
- { /* 采用头尾链表存储结构,求广义表L的深度。算法5.5 */
- 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->a.ptr.tp)
- {
- dep = GListDepth(pp->a.ptr.hp); /* 求以pp->a.ptr.hp为头指针的子表深度 */
- if (dep > max)
- max = dep;
- }
- return max + 1; /* 非空表的深度是各元素的深度的最大值加1 */
- }
-
- Status GListEmpty(GList L)
- { /* 判定广义表是否为空 */
- if (!L)
- return TRUE;
- else
- return FALSE;
- }
-
- GList GetHead(GList L)
- { /* 取广义表L的头 */
- GList h, p;
- if (!L)
- {
- printf("空表无表头!\n");
- exit(0);
- }
- p = L->a.ptr.tp;
- L->a.ptr.tp = NULL;
- CopyGList(&h, L);
- L->a.ptr.tp = p;
- return h;
- }
-
- GList GetTail(GList L)
- { /* 取广义表L的尾 */
- GList t;
- if (!L)
- {
- printf("空表无表尾!\n");
- exit(0);
- }
- CopyGList(&t, L->a.ptr.tp);
- return t;
- }
-
- Status InsertFirst_GL(GList *L, GList e)
- { /* 初始条件: 广义表存在 */
- /* 操作结果: 插入元素e作为广义表L的第一元素(表头,也可能是子表) */
- GList p = (GList)malloc(sizeof(GLNode));
- if (!p)
- exit(OVERFLOW);
- p->tag = LIST;
- p->a.ptr.hp = e;
- p->a.ptr.tp = *L;
- *L = p;
- return OK;
- }
-
- Status DeleteFirst_GL(GList *L, GList *e)
- { /* 初始条件: 广义表L存在 */
- /* 操作结果: 删除广义表L的第一元素,并用e返回其值 */
- GList p;
- *e = (*L)->a.ptr.hp;
- p = *L;
- *L = (*L)->a.ptr.tp;
- free(p);
- return OK;
- }
-
- void Traverse_GL(GList L, void(*v)(AtomType))
- { /* 利用递归算法遍历广义表L */
- if (L) /* L不空 */
- if (L->tag == ATOM) /* L为单原子 */
- v(L->a.atom);
- else /* L为广义表 */
- {
- Traverse_GL(L->a.ptr.hp, v);
- Traverse_GL(L->a.ptr.tp, v);
- }
- }
-
-
- /* --------------------------------------------------------------------------------------------------*/
-
-
-
- /* 广义表的书写形式串为HString类型 */
-
-
-
-
-
- /* ---------------------------------- 串的堆分配存储 -----------------------------------*/
-
- typedef struct
- {
- char *ch; /* 若是非空串,则按串长分配存储区,否则ch为NULL */
- int length; /* 串长度 */
- }HString;
-
- /* ---------------------------------------------------------------------------------------------*/
-
-
- /* ------------------------- 需要用到的串采用堆分配存储结构的基本操作 ------------------------*/
-
-
- Status StrAssign(HString *T, char *chars)
- { /* 生成一个其值等于串常量chars的串T */
- int i, j;
- if ((*T).ch)
- free((*T).ch); /* 释放T原有空间 */
- i = strlen(chars); /* 求chars的长度i */
- if (!i)
- { /* chars的长度为0 */
- (*T).ch = NULL;
- (*T).length = 0;
- }
- else
- { /* chars的长度不为0 */
- (*T).ch = (char*)malloc(i * sizeof(char)); /* 分配串空间 */
- if (!(*T).ch) /* 分配串空间失败 */
- exit(OVERFLOW);
- for (j = 0; j < i; j++) /* 拷贝串 */
- (*T).ch[j] = chars[j];
- (*T).length = i;
- }
- return OK;
- }
-
- Status StrCopy(HString *T, HString S)
- { /* 初始条件:串S存在。操作结果: 由串S复制得串T */
- int i;
- if ((*T).ch)
- free((*T).ch); /* 释放T原有空间 */
- (*T).ch = (char*)malloc(S.length * sizeof(char)); /* 分配串空间 */
- if (!(*T).ch) /* 分配串空间失败 */
- exit(OVERFLOW);
- for (i = 0; i < S.length; i++) /* 拷贝串 */
- (*T).ch[i] = S.ch[i];
- (*T).length = S.length;
- return OK;
- }
-
- Status StrEmpty(HString S)
- { /* 初始条件: 串S存在。操作结果: 若S为空串,则返回TRUE,否则返回FALSE */
- if (S.length == 0 && S.ch == NULL)
- return TRUE;
- else
- return FALSE;
- }
-
- int StrCompare(HString S, HString T)
- { /* 若S>T,则返回值>0;若S=T,则返回值=0;若S<T,则返回值<0 */
- int i;
- for (i = 0; i < S.length&&i < T.length; ++i)
- if (S.ch[i] != T.ch[i])
- return S.ch[i] - T.ch[i];
- return S.length - T.length;
- }
-
- int StrLength(HString S)
- { /* 返回S的元素个数,称为串的长度 */
- return S.length;
- }
-
- Status ClearString(HString *S)
- { /* 将S清为空串 */
- if ((*S).ch)
- {
- free((*S).ch);
- (*S).ch = NULL;
- }
- (*S).length = 0;
- return OK;
- }
-
- Status SubString(HString *Sub, HString S, int pos, int len)
- { /* 用Sub返回串S的第pos个字符起长度为len的子串。 */
- /* 其中,1≤pos≤StrLength(S)且0≤len≤StrLength(S)-pos+1 */
- int i;
- if (pos<1 || pos>S.length || len<0 || len>S.length - pos + 1)
- return ERROR;
- if ((*Sub).ch)
- free((*Sub).ch); /* 释放旧空间 */
- if (!len) /* 空子串 */
- {
- (*Sub).ch = NULL;
- (*Sub).length = 0;
- }
- else
- { /* 完整子串 */
- (*Sub).ch = (char*)malloc(len * sizeof(char));
- if (!(*Sub).ch)
- exit(OVERFLOW);
- for (i = 0; i <= len - 1; i++)
- (*Sub).ch[i] = S.ch[pos - 1 + i];
- (*Sub).length = len;
- }
- return OK;
- }
-
- void InitString(HString *T)
- { /* 初始化(产生空串)字符串T。另加 */
- (*T).length = 0;
- (*T).ch = NULL;
- }
-
-
- /* -----------------------------------------------------------------------------------------------*/
-
-
-
- Status sever(HString *str, HString *hstr)
- { /* 将非空串str分割成两部分:hstr为第一个','之前的子串,str为之后的子串 */
- int n, i = 1, k = 0; /* k记尚未配对的左括号个数 */
- HString ch, c1, c2, c3;
- InitString(&ch); /* 初始化HString类型的变量 */
- InitString(&c1);
- InitString(&c2);
- InitString(&c3);
- StrAssign(&c1, ",");
- StrAssign(&c2, "(");
- StrAssign(&c3, ")");
- n = StrLength(*str);
- do
- {
- SubString(&ch, *str, i, 1);
- if (!StrCompare(ch, c2))
- ++k;
- else if (!StrCompare(ch, c3))
- --k;
- ++i;
- } while (i <= n && StrCompare(ch, c1) || k != 0);
- if (i <= n)
- {
- StrCopy(&ch, *str);
- SubString(hstr, ch, 1, i - 2);
- SubString(str, ch, i, n - i + 1);
- }
- else
- {
- StrCopy(hstr, *str);
- ClearString(str);
- }
- return OK;
- }
-
- Status CreateGList(GList *L, HString S)
- { /* 采用头尾链表存储结构,由广义表的书写形式串S创建广义表L。设emp="()" */
- HString emp, sub, hsub;
- GList p, q;
- InitString(&emp);
- InitString(&sub);
- InitString(&hsub);
- StrAssign(&emp, "()");
- if (!StrCompare(S, emp)) /* 创建空表 */
- *L = NULL;
- else
- {
- *L = (GList)malloc(sizeof(GLNode));
- if (!*L) /* 建表结点不成功 */
- exit(OVERFLOW);
- if (StrLength(S) == 1) /* 创建单原子广义表 */
- {
- (*L)->tag = ATOM;
- (*L)->a.atom = S.ch[0];
- }
- else
- {
- (*L)->tag = LIST;
- p = *L;
- SubString(&sub, S, 2, StrLength(S) - 2); /* 脱外层括号 */
- do /* 重复建n个子表 */
- {
- sever(&sub, &hsub); /* 从sub中分离出表头串hsub */
- CreateGList(&p->a.ptr.hp, hsub);
- q = p;
- if (!StrEmpty(sub)) /* 表尾不空 */
- {
- p = (GList)malloc(sizeof(GLNode));
- if (!p)
- exit(OVERFLOW);
- p->tag = LIST;
- q->a.ptr.tp = p;
- }
- } while (!StrEmpty(sub));
- q->a.ptr.tp = NULL;
- }
- }
- return OK;
- }
-
-
-
-
- /* 主程序 */
-
-
- void visit(AtomType e)
- {
- printf("%c ", e);
- }
-
- void main()
- {
- char p[80];
- GList l, m;
- HString t;
- InitString(&t);
- InitGList(&l);
- InitGList(&m);
- printf("空广义表l的深度=%d l是否空?%d(1:是 0:否)\n", GListDepth(l), GListEmpty(l));
- printf("请输入广义表l(书写形式:空表:(),单原子:a,其它:(a,(b),b)):\n");
- gets(p);
- StrAssign(&t, p);
- CreateGList(&l, t);
- printf("广义表l的长度=%d\n", GListLength(l));
- printf("广义表l的深度=%d l是否空?%d(1:是 0:否)\n", GListDepth(l), GListEmpty(l));
- printf("遍历广义表l:\n");
- Traverse_GL(l, visit);
- printf("\n复制广义表m=l\n");
- CopyGList(&m, l);
- printf("广义表m的长度=%d\n", GListLength(m));
- printf("广义表m的深度=%d\n", GListDepth(m));
- printf("遍历广义表m:\n");
- Traverse_GL(m, visit);
- DestroyGList(&m);
- m = GetHead(l);
- printf("\nm是l的表头,遍历广义表m:\n");
- Traverse_GL(m, visit);
- DestroyGList(&m);
- m = GetTail(l);
- printf("\nm是l的表尾,遍历广义表m:\n");
- Traverse_GL(m, visit);
- InsertFirst_GL(&m, l);
- printf("\n插入l为m的表头,遍历广义表m:\n");
- Traverse_GL(m, visit);
- printf("\n删除m的表头,遍历广义表m:\n");
- DestroyGList(&l);
- DeleteFirst_GL(&m, &l);
- Traverse_GL(m, visit);
- printf("\n");
- DestroyGList(&m);
- }
运行结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。