問題及代碼:
文件名:main.cpp glist.cpp glist.h
作者:鄭孚嘉
問題描述:
(1)建立廣義表算法庫,包括:
① 頭文glist.h,定義數據類型,聲明函數;
② 源文件glist.cpp,實現廣義表的基本運算,主要算法包括:
int GLLength(GLNode *g);//求廣義表g的長度int GLDepth(GLNode *g);//求廣義表g的深度GLNode
*CreateGL(char *&s);//返回由括號表示法表示s的廣義錶鏈式存儲結構void DispGL(GLNode *g);//輸出廣義表g
③ 設計main函數,測試上面實現的算法
(2)設計一個算法,求出給定廣義表g中的原子個數
(3)設計一個算法,求出給定廣義表g中的最大原子
頭文件:glist.h,包含定義廣義表數據結構的代碼、宏定義、要實現算法的函數的聲明
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
源文件:glist.cpp,包含實現各種算法的函數的定義
#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); //遞歸輸出後續表的內容
}
}
}
(1)
main.cpp
#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;
}
運行結果:
(2)(3)
main.cpp
#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;
}
運行結果:
知識點總結:
求出了廣義表的長度深度和原子個數及大小,廣義表的長度是去掉一層括號剩下的是幾部分,廣義表的深度是去掉幾層括號可以到最後一部分。