广义表算法库及应用
为了丰富算法库,以应对各类工程的需要,本次实践将进行广义表算法库的建立以及应用。
项目要求一:
建立广义表算法库,包括:
① 头文glist.h,定义数据类型,声明函数;
② 源文件glist.cpp,实现广义表的基本运算,主要算法包括:
int GLLength(GLNode *g); //求广义表g的长度
int GLDepth(GLNode *g); //求广义表g的深度
GLNode *CreateGL(char *&s); //返回由括号表示法表示s的广义表链式存储结构
void DispGL(GLNode *g); //输出广义表g
本次算法库的建设需要应用多文件组织工程,这里不再介绍详细过程,可以点击此处参考。
建立好之后的工作空间截图如下:
实现的源代码如下:
1.glist.h
- //*Copyright (c)2017,烟台大学计算机与控制工程学院*
- //*All rights reservrd.*
- //*文件名称 :glist.h*
- //*作者:侯成健*
- //*完成时间:2017年11月16日*
- //*版本号:v1.0*
- //*问题描述:包含定义广义表表示数据结构的代码、宏定义、要实现算法的函数的声明*
- //*输入描述:无*
- //*程序输出:无
- #ifndef GLIST_H_INCLUDED
- #define GLIST_H_INCLUDED
- typedef char ElemType;
- typedef struct lnode
- {
- int tag; //节点类型标识
- union
- {
- ElemType data; //原子值
- struct lnode *sublist; //指向子表的指针
- } val;
- struct lnode *link; //指向下一个元素
- } GLNode; //广义表节点类型定义
- int GLLength(GLNode *g); //求广义表g的长度
- int GLDepth(GLNode *g); //求广义表g的深度
- GLNode *CreateGL(char *&s); //返回由括号表示法表示s的广义表链式存储结构
- void DispGL(GLNode *g); //输出广义表g
- #endif // GLIST_H_INCLUDED
2.glist.cpp
- //*Copyright (c)2017,烟台大学计算机与控制工程学院*
- //*All rights reservrd.*
- //*文件名称 :glist.cpp*
- //*作者:侯成健*
- //*完成时间:2017年11月16日*
- //*版本号:v1.0*
- //*问题描述:包含各类函数的实现*
- //*输入描述:无*
- //*程序输出:无
- #include <stdio.h>
- #include <malloc.h>
- #include "glist.h"
- int GLLength(GLNode *g) //求广义表g的长度
- {
- int n=0;
- GLNode *g1;
- g1=g->val.sublist; //g指向广义表的第一个元素
- while (g1!=NULL)
- {
- n++; //累加元素个数
- g1=g1->link;
- }
- return n;
- }
- int GLDepth(GLNode *g) //求广义表g的深度
- {
- GLNode *g1;
- int max=0,dep;
- if (g->tag==0) //为原子时返回0
- return 0;
- g1=g->val.sublist; //g1指向第一个元素
- if (g1==NULL) //为空表时返回1
- return 1;
- while (g1!=NULL) //遍历表中的每一个元素
- {
- if (g1->tag==1) //元素为子表的情况
- {
- dep=GLDepth(g1); //递归调用求出子表的深度
- if (dep>max) //max为同一层所求过的子表中深度的最大值
- max=dep;
- }
- g1=g1->link; //使g1指向下一个元素
- }
- return(max+1); //返回表的深度
- }
- GLNode *CreateGL(char *&s) //返回由括号表示法表示s的广义表链式存储结构
- {
- GLNode *g;
- char ch=*s++; //取一个字符
- if (ch!='\0') //串未结束判断
- {
- g=(GLNode *)malloc(sizeof(GLNode));//创建一个新节点
- if (ch=='(') //当前字符为左括号时
- {
- g->tag=1; //新节点作为表头节点
- g->val.sublist=CreateGL(s); //递归构造子表并链到表头节点
- }
- else if (ch==')')
- g=NULL; //遇到')'字符,g置为空
- else if (ch=='#') //遇到'#'字符,表示为空表
- g=NULL;
- else //为原子字符
- {
- g->tag=0; //新节点作为原子节点
- g->val.data=ch;
- }
- }
- else //串结束,g置为空
- g=NULL;
- ch=*s++; //取下一个字符
- if (g!=NULL) //串未结束,继续构造兄弟节点
- {
- if (ch==',') //当前字符为','
- g->link=CreateGL(s); //递归构造兄弟节点
- else //没有兄弟了,将兄弟指针置为NULL
- g->link=NULL;
- }
- return g; //返回广义表g
- }
- void DispGL(GLNode *g) //输出广义表g
- {
- if (g!=NULL) //表不为空判断
- {
- //先处理g的元素
- if (g->tag==0) //g的元素为原子时
- printf("%c", g->val.data); //输出原子值
- else //g的元素为子表时
- {
- printf("("); //输出'('
- if (g->val.sublist==NULL) //为空表时
- printf("#");
- else //为非空子表时
- DispGL(g->val.sublist); //递归输出子表
- printf(")"); //输出')'
- }
- if (g->link!=NULL)
- {
- printf(",");
- DispGL(g->link); //递归输出后续表的内容
- }
- }
- }
3.main.cpp
- //*Copyright (c)2017,烟台大学计算机与控制工程学院*
- //*All rights reservrd.*
- //*文件名称 :main.cpp*
- //*作者:侯成健*
- //*完成时间:2017年11月16日*
- //*版本号:v1.0*
- //*问题描述:测试函数*
- //*输入描述:无*
- //*程序输出:无
- #include <stdio.h>
- #include "glist.h"
- int main()
- {
- GLNode *g;
- char *s="(b,(b,a,(#),d),((a,b),c((#))))";
- g = CreateGL(s);
- DispGL(g);
- printf("广义表长度:%d\n", GLLength(g));
- printf("广义表深度:%d\n", GLDepth(g));
- return 0;
- }
测试结果截图如下:
项目要求二:
设计一个算法,求出给定广义表g中的原子个数
设计一个算法,求出给定广义表g中的最大原子
设计一个算法,求出给定广义表g中的最大原子
用以上的算法库,利用测试函数来实现要求
源代码:main.cpp
- //*Copyright (c)2017,烟台大学计算机与控制工程学院*
- //*All rights reservrd.*
- //*文件名称 :main.cpp*
- //*作者:侯成健*
- //*完成时间:2017年11月16日*
- //*版本号:v1.0*
- //*问题描述:测试函数*
- //*输入描述:无*
- //*程序输出:无
- #include <stdio.h>
- #include "glist.h"
- int atomnum(GLNode *g) //求广义表g中的原子个数
- {
- if (g!=NULL)
- {
- if (g->tag==0)
- return 1+atomnum(g->link);
- else
- return atomnum(g->val.sublist)+atomnum(g->link);
- }
- else
- return 0;
- }
- ElemType maxatom(GLNode *g) //求广义表g中最大原子
- {
- ElemType max1,max2;
- if (g!=NULL)
- {
- if (g->tag==0)
- {
- max1=maxatom(g->link);
- return(g->val.data>max1?g->val.data:max1);
- }
- else
- {
- max1=maxatom(g->val.sublist);
- max2=maxatom(g->link);
- return(max1>max2?max1:max2);
- }
- }
- else
- return 0;
- }
- int main()
- {
- GLNode *g;
- char *s="(b,(b,a,(#),d),((a,b),c((#))))";
- g = CreateGL(s);
- DispGL(g);
- printf("\n");
- printf("原子个数 :%d\n", atomnum(g));
- printf("最大原子 :%c\n", maxatom(g));
- return 0;
- }
运行结果截图如下: