识别广义表头尾演示数据结构课程设计报告
- 格式:doc
- 大小:620.45 KB
- 文档页数:32
目录沈阳航空航天大学 ........................................................................... 错误!未定义书签。
学术诚信声明 ................................................................................... 错误!未定义书签。
1 题目介绍与功能描述 (1)1.1题目介绍 (1)1.2具体要求 (1)1.3题目分析 (1)2 系统功能模块结构图 (2)2.1系统功能结构图 (2)2.2主要模块功能说明 (3)2.2.1 建立广义表 (3)2.2.2 对表进行求头尾操作 (3)3 数据结构设计及用法说明 (4)3.1存储结构 (4)3.2用法说明 (4)4 主要函数 (5)4.1 VOID CREATLIST(GL IST &L S ) (5)4.2 VOID GL_E LEM(GL IST P) (7)4.3 VOID PRINTF_GL(GL IST L S,INT &I) (7)4.4 VOID G ET H EAD(GL IST &L S) (9)4.5 VOID G ET T AIL(GL IST &L S) (9)4.6 VOID G ET_HT(GL IST L S) (10)5 主要函数流程图 (12)5.1 MAIN函数 (12)5.2 CREATLIST函数 (13)5.3 PRINTF_GL函数 (14)6 调试报告 (15)6.1测试用例设计 (15)6.2调试过程 (15)6.3运行结果 (16)参考文献 (21)附录源程序清单 (22)1 题目介绍与功能描述1.1 题目介绍本课程设计主要完成对广义表的建立以及遍历(输出),并且对已建立的广义表实施操作,操作序列为一串由“t”、“h”以及“”组成的字符串。
《数据结构》课程设计报告设计题目航班信息的查询与检索专业电子信息工程班级姓名学号完成日期2010-6-28目录1. 问题描述………………………………………………页码2. 系统设计………………………………………………页码3. 数据结构与算法描述…………………………………页码4. 测试结果与分析………………………………………页码5. 总结…………………………………………………页码6. 参考文献………………………………………………页码附录程序源代码…………………………………………页码航班信息的查询与检索1. 问题描述:这学期,我们在余先伦老师的带领下,大致学习了一下《数据结构》,实现了简单的数据结构算法。
现在,我们将完成简单的数据结构课程设计。
在数据结构的学习中我们知道,排序和查找是在数据结构中使用频率非常高。
为了能够快速有效地进行查询与检索,我们需要对记录按关键字进行排列。
选择《航班信息查询与检索》这个课题,主要是因为当今时代的需求。
随着科技与经济的发展,当今乘飞机的人越来越多,这时,快速的了解各类航班的班次、时间、价格及机型的信息将备受关注。
在我开发的这个《航班信息查询与检索》这个系统中,航班号将成为关键字,而且是具有结构特点的一类关键字。
通过关键字的键入,你将获得你所需要的航班的全部信息。
2. 系统设计2.1 设计目标:通过一定的数据结构,实现对信息的查询与检索并按要求输出。
试设计一个航空客运定票系统。
[基本要求]每条航线所涉及的信息有:终点站名、航班号、飞机号、飞机周日(星期几)、乘员定额、余票量、订定票的客户名单(包括姓名、订票量、舱位等级1,2或3)以及等候替补的客户名单(包括姓名、所需数量)。
系统能实现的操作和功能如下:1)查询航线:根据客户提出的终点站名输出如下信息:航班号、飞机号、星期几飞行,最近一天航班的日期和余票额;2)承办订票业务:根据客户提出的要求(航班号、订票数额)查询该航班票额情况,若有余票,则为客户办理订票手续,输出座位号;若已满员或余票少余订票额,则需重新询问客户要求。
《数据结构》课程设计报告范本(doc 8页)《数据结构》课程设计报告一、课程设计的内容、要求1 线性表的另一种实现。
对顺序表空间被耗尽问题的一个解决办法是:当数组溢出时,用一个更大的数组替换该数组。
一个较好的法则是:当出现溢出时,数组长度加长一倍具有较高的时间和空间效率。
参照教材中顺序表的有关内容,按上面的要求实现顺序表,并测试当数组溢出时你的实现的运作情况。
二、所采用的数据结构ADT List{数据对象: D = {a i|a i ∈ElemSet, i=1,2…n>=0}数据关系: R1={<a i-1, a i>|a i-1, a i∈D, i=1,2,…,n}基本操作:void IniList(SqList& L);void DestroyList(SqList& L);bool ListEmpty(SqList L);int ListLength(SqList L);void GetElem(SqList L, int i, Elem &e);bool PriorElem(SqList L, Elem cur_e, Elem &pre_e);bool NextElem(SqList L, Elem cur_e, Elem &next_e);void ListInsert(SqList &L, int i, Elem e);void ListDelete(SqList &L, int i);void ClearList(SqList& L);}三、主要模块(或函数)及其功能typedef struct LIST{ElemType *data;int size;int max_size;}LIST;void InitList(LIST *list)//初始化{list->data = (int*)malloc(sizeof(ElemType)*INIT_SIZE);list->size = 0;list->max_size = INIT_SIZE;}void DestroyList(LIST &list){}bool NextElem(LIST list,int cur_e,int &next_e)//后继{if(cur_e < 0 || cur_e > list.size) return false;else{next_e = cur_e + 1;return true;}}void Insert(LIST *list,ElemType value){if(list->size>=list->max_size){int i;ElemType *temp = (int*)malloc(sizeof(ElemType)*list->size*2);cout<<endl<<"线性表原容量改变:原大小为"<<list->max_size;for(i=0;i<list->size;i++){temp[i] = list->data[i];}free(list->data);list->data = temp;list->max_size*=2;cout<<"改变后大小"<<list->max_size<<endl;}list->data[list->size] = value;list->size++;}void Insert_Back(LIST *list,int idx,ElemType value){if(list->size>=list->max_size){int i;ElemType *temp = (int*)malloc(sizeof(ElemType)*list->size*2);cout<<endl<<"线性表原容量改变:原大小为"<<list->max_size;for(i=0;i<list->size;i++){temp[i] = list->data[i];}free(list->data);list->data = temp;list->max_size*=2;cout<<"改变后大小"<<list->max_size<<endl;}if(idx>list->size){list->data[list->size] = value;}else{int i;for(i=list->size;i>idx;i--){list->data[i] = list->data[i-1];}list->data[idx] = value;}list->size++;}void ListDelete(LIST *list,int i,ElemType *e)//删除一个元素{int j;*e=list->data[i];for(j=i+1;j<=list->size-1;j++)list->data[j-1]=list->data[j];list->size--;}void Print_list(LIST *list){int i;if(list->size == 0){cout<<"当前线性表内没有元素。
《数据结构》课程设计报告题目猴子选大王学生姓名学号专业班级指导老师设计日期 2009年12月19日指导老师评阅意见:一、问题定义1、课程设计目的:数据结构课程设计是学习数据结构课程的一个重要环节。
能巩固和加深课堂教学内容,提高学生实际工作能力,培养科学作风,为学习后续课程和今后的系统开发奠定基础。
通过课程设计,使学生熟练掌握数据结构课程中所学的理论知识,并实际应用,通过综合运用数据结构的基本知识来解决实际问题,加强学生分析和解决问题的能力。
2、课程设计的要求:本次课程设计要求学生正确理解课题,考虑问题要细致,全面,解决问题的方法要科学合理,切合实际。
并能上机实现。
3、课程设计的意义:1、有利于基础知识的理解。
学生对计算机运行的机理等知识内容的理解比较肤浅。
如果接触了程度设计,就能真正理解,从而进一步打破计算机的神秘感。
2、有利于逻辑思维的锻炼。
程序设计是公认的、最能直接有效地训练学生的创新思维,培养分析问题、解决问题能力的学科之一。
即使一个简单的程序,从任务分析、确定算法、界面布局、编写代码到调试运行,整个过程学生都需要有条理地构思,这中间有猜测设想、判断推理的抽象思维训练,也有分析问题、解决问题、预测目标等能力的培养。
3、有利于治学态度的培养。
程序设计中,语句的语法和常量变量的定义都有严格的要求,有时输了一个中文标点、打错了一个字母,编译就不通过,程序无法正常运行。
因此,程序设计初学阶段,学生经常会犯这样的错误,可能要通过几次乃至十多次的反复修改、调试,才能成功,但这种现象会随着学习的深入而慢慢改观。
这当中就有一个严谨治学、一丝不苟的科学精神的培养,又有一个不怕失败、百折不挠品格的锻炼猴子选大王任务:一堆猴子都有编号,编号是1,2,3 ...m ,这群猴子(m个)按照1-m的顺序围坐一圈,从第1开始数,每数到第N个,该猴子就要离开此圈,这样依次下来,直到圈中只剩下最后一只猴子,则该猴子为大王。
广义表的head和tail运算讲解一、引言广义表是一种常用的数据结构,它可以包含任意类型的元素,包括其他广义表。
广义表的h ea d运算和ta il运算是对广义表进行操作的两个基础运算,本文将对这两个运算进行详细讲解。
二、广义表的定义广义表是指可以包含各种元素的线性表,其中的元素可以是原子元素(如整数、字符等),也可以是广义表。
广义表由一系列元素组成,用括号表示,元素之间用逗号隔开。
三、h e a d运算h e ad运算用于获取广义表的第一个元素。
下面是h ea d运算的示意图:```广义表:(a,b,c,d,...)h e ad运算结果:a```四、t a i l运算t a il运算用于获取广义表除第一个元素外的剩余元素组成的广义表。
下面是t ai l运算的示意图:```广义表:(a,b,c,d,...)t a il运算结果:(b,c,d,...)```五、示例与应用假设有一个广义表`(1,(2,3),(4,(5,6)))`,我们可以通过h ea d运算和ta il运算来获取广义表中的元素。
-对该广义表进行hea d运算,将返回第一个元素1。
-对该广义表进行ta i l运算,将返回剩余元素组成的广义表`(2,3)`。
广义表的he ad和t ai l运算可以应用于各种场景。
例如,在处理嵌套列表时,可以通过递归地使用he ad和t ai l运算,来遍历并处理广义表中的所有元素。
以下是一个示例代码,演示了如何使用he a d和ta il运算来遍历广义表:```p yt ho n定义一个函数,用于遍历广义表d e ft ra ve rs e(ls t):i f ls t==[]:r e tu rnp r in t(ls t.he ad())t r av er se(l st.t ail())调用函数进行遍历l s t=Li st(1,L is t(2,Li st(3,L is t(4,L i st(5)))))t r av er se(l st)```通过以上示例,我们可以清晰地看到广义表的he ad和t ai l运算在遍历广义表时的作用。
广义表实验:广义表基本操作实现实验目的:1、熟悉的存储方式;2、通过实验,深入理解递归以及广义表中的递归实现;实验要求:1、在vc++或tc环境下实现基本功能;2、先完成基本功能,基本功能为必做内容,有多余时间的同学可以做选做的内容;3、独自完成实验操作,并给出相关的数据;4、每次实验后,撰写实验报告,并在下星期一由学习委员收集并按学号整理好后,交任课教师。
实验内容及步骤:必做题:1、由字符串构建一个广义表;2、输出该广义表;3、求广义表的长度和深度;选做:1、求广义表的表头、表尾;2、输出广义表的所有的原子,并求该广义表中的最大原子;附:程序可以使用参考的,更提倡自己编写,使用参考程序的同学把函数的功能读懂,并用实例去走一遍。
参考程序:#include"stdio.h"#include"malloc.h"typedef char elemtype;typedef struct lnode{int tag;union{elemtype data;struct lnode *sublist;}val;struct lnode *link;}glnode;glnode *creatgl(char *&s){glnode *h;char ch;ch=*s;s++;if(ch!='\0'){h=(glnode *)malloc(sizeof(glnode));if(ch=='('){h->tag=1;h->val.sublist=creatgl(s);}else if(ch==')')h=NULL;else{h->tag=0;h->val.data=ch;}}else h=NULL;ch=*s;s++;if(h!=NULL)if(ch==',')h->link=creatgl(s);elseh->link=NULL;return h;}int gllength(glnode *g) {int n=0;g=g->val.sublist;while(g){n++;g=g->link;}return n;}int gldepth(glnode *g) {int max=0,dep;if(g->tag==0)return 0;g=g->val.sublist;if(g==NULL)return 1;while(g){if(g->tag==1){dep=gldepth(g);if(dep>max)max=dep;}g=g->link;}return(max+1);}void dispgl(glnode *g){if(g){if(g->tag==1){printf("(");if(g->val.sublist==NULL)printf("");elsedispgl(g->val.sublist);}elseprintf("%c",g->val.data);if(g->tag==1)printf(")");if(g->link){printf(",");dispgl(g->link);}}}void main(){glnode *g;char *s="(a,(b,c),d,(e,(f,g)))";g=creatgl(s);printf("输出广义表g:");dispgl(g);printf("\n");printf("输出广义表g的长度:");printf("%d\n",gllength(g));printf("输出广义表g的深度:");printf("%d\n",gldepth(g));}。
《数据结构》课程设计题目:广义表的运算广义表是线性表的推广。
线性表的元素仅限于原子项。
广义表的元素或者是原子,或者是一个广义表,有其自身结构。
广义表通常用圆括号括起来,用逗号分隔其中的元素。
为了区分原子和广义表,书写时用大写字母表示广义表,用小写字母表示原子。
LS=(a1,a2,…,an),LS是广义表的名字,n为它的长度,若ai是广义表,则称它为LS的子表。
若广义表非空(n>=1),则a1是LS的表头,其余元素组成的表(a2,…,an)称为LS的表尾。
一个表展开后所含括号的层数称为广义表的深度。
本设计要求实现广义表的建立、查找、输出、取表头、取表尾及求深度等运算。
选择合适的存储结构表示广义表,并能实现下列运算要求:(1)用大写字母表示广义表,用小写字母表示原子,并提供设置广义表的值的功能。
(2)取广义表L的表头和表尾的函数head(L)和tail(L)。
(3)能用这两个函数的复合形式求出广义表中的指定元素。
(4)由广义表的字符串形式到广义表的转换函数Lists Str_ToLists_(S);例如Str_ToLists_(“ (a,(a,b),c)”)的值为一个广义表。
(5)由广义表到广义表的字符串形式的转换函数char * Lists_To_Str(L)。
(6)最好能设置多个广义表。
解:本题的解法如下:1算法设计1.由于广义表(a1,a2,…,an)中的数据元素可以具有不同的结构(或是原子或是列表)因此难以用顺序存储结构表示,通常采取链式存储结构,每个元素都可以用一个结点表示。
一个表结点可由3个域组成:标志域,指针表头的指针域和指针表尾的指针域;而原子结点只需两个域:标志域和值域。
2.假设以字符串L=(a1,a2,…,an) 的形式定义广义表L,建立相应的存储结构。
对广义表进行的操作下递归定义时,可以有两种方法。
一种是把广义表分解成表头和表尾两部分;另一种是把广义表堪称含有n个并列子表(假设原子也视作子表)的表。
《数据结构》实验报告实验题目:广义表的创建与遍历实验目的:熟悉和掌握广义表的定义及结构,可以创建及遍历广义表。
实验内容:利用栈创建以及遍历一个广义表。
一、需求分析1.本演示程序中,输入广义表的内容应为任意符合广义表要求结构的数据,将数据输入创建广义表中,再通过遍历程序将其以广义表形式输出。
2.本程序是以用户与计算机的对话方式执行,运行程序后,按要求输入数据即可。
3.程序执行的命令包括:(1)构造广义表与链栈,并初始化(2)输入广义表(3)输出广义表(4)结束4.测试数据:输入((),((a,b),(c,d))) 输出((),((a,b),(c,d)))错误输入:如果输入((),((a,b),(c,d)))) 输出((),((a,b),(c,d)))二概要设计为了实现上述操作,应以广义链表为存储结构。
1.基本操作:Snode *Push(Snode *top,node *input)实现指针入栈Snode *Pop(Snode *top,node **output)实现指针出栈node *create()广义表的建立void print(node *head)广义表的输出2.本程序包括三个模块:(1)主程序模块(2)广义表的创建(3)广义表的遍历(4)入栈模块(5)出栈模块(6)模块调用图:三 详细设计1.元素类型、节点类型和指针类型//定义广义表typedef struct node{char data; /*存储数据*/int tag; /*用以标记,标记为1时为左括号,标记为0时为字符,标记为-1时为新开辟节点*/struct node *hp; /*该指针指向字表*/struct node *tp; /*该指针指向后续节点*/}node;//定义链栈typedef struct Snode{node *data;struct Snode *next;}Snode;Snode *topnode *inputSnode *sSnode *p;node **outputnode *p,*q,*head;2.每个模块的分析:(1) 主程序模块:int main(){node *head;printf("请输入广义表:\n");head=create();printf("该广义表为:\n");print(head);getchar();getchar();return 0;}(2)广义表的创建:node *create(){node *p,*q,*head; /*指针p是一个移动指针,指针q用以开辟新节点,head为头指针*/char x; /*输入字符*/Snode *top; /*栈顶指针*/top=NULL; /*栈顶置空*/q=(node *)malloc(sizeof(node)); /*申请新节点*/q->tag=1; /*广义表形式第一个字符必为左括号*/scanf("%c",&x); /*输入字符*/head=q; /*广义表头结点指向新开辟节点*/p=head; /*活动指针指向头结点*/top=Push(top,p); /*该节点指针入栈*/q=(node *)malloc(sizeof(node)); /*开辟新节点*/q->tag=-1; /*新节点标记为-1*/p->hp=q; /*上一个读到的是左括号,将新节点链到当前节点的子表*/p->tag=1; /*当前节点为左括号,标记为1*/p->data=NULL; /*当前节点数据域为空*/p=p->hp; /*活动指针移到当前节点的子表*/scanf("%c",&x); /*接着输入数据*/while(top!=NULL) /*遇到左括号进栈,右括号退栈,栈空循环结束*/{if(x=='(') /*遇到左括号*/{q=(node *)malloc(sizeof(node)); /*申请新节点*/q->tag=-1; /*新节点标记均为-1*/p->hp=q; /*新节点链到当前节点的子表*/p->tag=1; /*因是左括号,当前节点标记为1*/p->data=NULL; /*数据域为空*/top=Push(top,p); /*指针入栈*/p=p->hp; /*移动指针到当前节点的子表*/}else if(x==',') /*遇到逗号*/{q=(node *)malloc(sizeof(node)); /*申请新节点,标记-1*/q->tag=-1;p->tp=q; /*新节点链到当前节点后续节点*/p=p->tp; /*移动指针到当前节点的后续*/}else if(x==')') /*遇到右括号*/{p->tp=NULL; /*后续域置空*/top=Pop(top,&p); /*栈顶指针退栈*/ }else /*遇到其他字符*/{p->tag=0; /*标记为0*/p->data=x; /*数据域存数据*/p->hp=NULL; /*子表指向置空*/ }scanf("%c",&x); /*再读下一个字符*/ }p->tp=NULL; /*循环结束,当前节点后续置空*/return(head);(3)广义表的遍历:void print(node *head){node *p;Snode *top;p=head;top=NULL; /*栈置空*/while(p!=NULL||top!=NULL) /*p空且栈空时退出循环*/{if(p!=NULL) /*如果活动指针不空,做三个判断*/{if(p->tag==1) /*标记为1输出左括号,指针进栈,活动指针下移*/{top=Push(top,p);printf("(");p=p->hp;}else if(p->tag==0) /*标记为0,输出字符,如果后续不空,输出逗号*/{printf("%c",p->data);if(p->tp!=NULL){printf(",");}p=p->tp;}else if(p->tag==-1) /*标记为-1,先出栈,出栈后p上移输出右括号,如果后续不空,输出逗号*/{top=Pop(top,&p);printf(")");if(p->tp!=NULL){printf(",");}p=p->tp;}}else /*若p空,表示该层结束*/{top=Pop(top,&p); /*退栈,指针上移,若上移后仍不为空,且此时栈必定不空,输出右括号*/printf(")");if(p->tp!=NULL) /*若后续不为空,需输出逗号,指针后移*/{printf(",");}p=p->tp;}}printf("\n");}(4)入栈模块:Snode *Push(Snode *top,node *input){Snode *s;s=(Snode *)malloc(sizeof(Snode)); /*申请新节点*/s->data=input;s->next=top;top=s;return(top);}(5)出栈模块:Snode *Pop(Snode *top,node **output){Snode *p;if (top==NULL){*output=NULL;return NULL;}else{*output=top->data;p=top;top=top->next;free(p);return(top);}}3.完整的程序:(见源文件).四使用说明、测试分析及结果1.程序使用说明:(1)本程序的运行环境为VC6.0。
广义表实验报告一、实验目的广义表是一种非线性的数据结构,本次实验的主要目的是深入理解广义表的概念、存储结构和基本操作,并通过编程实现对广义表的各种操作,以提高对数据结构的理解和编程能力。
二、实验环境本次实验使用的编程语言是C++,编译环境为Visual Studio 2019。
三、广义表的概念广义表是线性表的推广,它允许表中的元素本身也是一个广义表。
广义表通常用一对圆括号“()”来表示,元素之间用逗号“,”分隔。
例如,(a, (b, c), d) 就是一个广义表,其中 a、d 是原子元素,(b, c) 是子表。
广义表可以分为表头和表尾两部分。
表头是广义表的第一个元素,表尾是除表头外的其余元素组成的广义表。
例如,对于广义表(a, (b,c), d),表头是 a,表尾是((b, c), d)。
四、广义表的存储结构1、头尾链表存储结构每个节点包含一个标志位 tag,用于区分原子节点和子表节点。
当 tag = 0 时,为原子节点,包含一个数据域 atom 和一个指向下一个节点的指针 next。
当 tag = 1 时,为子表节点,包含一个指向表头节点的指针 hp 和一个指向表尾节点的指针 tp。
2、扩展线性链表存储结构每个节点包含一个标志位 tag、一个数据域 data 和两个指针域 hp和 tp。
当 tag = 0 时,data 存储原子元素的值,hp 和 tp 均为 NULL。
当 tag = 1 时,data 为 NULL,hp 指向表头节点,tp 指向表尾节点。
五、广义表的基本操作1、创建广义表输入广义表的字符串表示,通过递归算法构建广义表的存储结构。
2、输出广义表以递归的方式遍历广义表的存储结构,输出广义表的字符串表示。
3、求广义表的深度递归地计算每个子表的深度,广义表的深度为所有子表深度的最大值加 1。
4、求广义表的长度遍历广义表的存储结构,统计原子节点和子表节点的个数。
5、复制广义表递归地复制广义表的每个节点,创建一个新的广义表存储结构。
广义表课程设计一、教学目标本课程的教学目标是使学生掌握广义表的基本概念、性质和操作算法,培养学生运用广义表解决实际问题的能力。
具体目标如下:1.知识目标:(1)了解广义表的定义、基本性质和运算规则;(2)掌握广义表的深度和长度概念,并能运用其判断和计算;(3)熟悉广义表的递归表示方法,理解递归的含义和应用;(4)掌握广义表的扩展运算,包括表的展开、逆序、求幂等;(5)了解广义表在计算机科学中的应用领域。
2.技能目标:(1)能够运用广义表表示和处理各种数据结构;(2)能够运用广义表解决实际问题,如编程实现递归算法;(3)能够运用广义表对算法进行优化和改进。
3.情感态度价值观目标:(1)培养学生的抽象思维能力,提高解决问题的综合素质;(2)培养学生勇于探索、创新的精神,培养合作意识;(3)使学生认识到广义表在计算机科学中的重要性,激发学生对计算机科学的热爱。
二、教学内容本课程的教学内容主要包括广义表的基本概念、性质和操作算法。
具体安排如下:1.第一章:广义表的基本概念,介绍广义表的定义、特点和表示方法;2.第二章:广义表的性质,包括广义表的长度、深度、递归表示等;3.第三章:广义表的运算,包括表的展开、逆序、求幂等操作;4.第四章:广义表的应用,介绍广义表在计算机科学中的应用领域和实例。
三、教学方法本课程采用讲授法、讨论法、案例分析法和实验法等多种教学方法,以激发学生的学习兴趣和主动性。
1.讲授法:通过教师的讲解,使学生掌握广义表的基本概念和性质;2.讨论法:引导学生分组讨论广义表的运算规则和应用实例,培养学生的合作意识;3.案例分析法:分析广义表在计算机科学中的应用实例,使学生了解广义表的实际价值;4.实验法:安排上机实验,让学生动手实践广义表的操作,提高学生的实际编程能力。
四、教学资源本课程的教学资源包括教材、参考书、多媒体资料和实验设备。
1.教材:选用《计算机科学基础》系列教材,为学生提供系统、科学的学习资源;2.参考书:推荐《广义表论》等参考书籍,丰富学生的知识体系;3.多媒体资料:制作课件、教学视频等,以图文并茂的形式呈现教学内容;4.实验设备:提供计算机实验室,让学生进行上机实验,提高实际操作能力。
数组和广义表课程设计一、教学目标本节课的学习目标主要包括以下三个方面:1.知识目标:通过本节课的学习,学生需要掌握数组和广义表的基本概念、性质和运算方法。
具体包括了解数组和广义表的定义、特点和应用场景,掌握数组的创建、访问和修改方法,以及广义表的创建、展开和递归操作。
2.技能目标:学生需要能够运用数组和广义表解决实际问题,具备一定的编程能力。
具体包括能够使用数组进行数据存储和处理,能够使用广义表进行复杂数据的表示和操作。
3.情感态度价值观目标:通过学习数组和广义表,学生能够培养对计算机科学的兴趣和热情,增强对算法和数据结构的理解和认识,提高解决问题的能力和创新思维。
二、教学内容本节课的教学内容主要包括数组和广义表的基本概念、性质和运算方法。
具体包括以下几个方面:1.数组的概念和性质:介绍数组的定义、特点和应用场景,讲解数组的创建、访问和修改方法。
2.广义表的概念和性质:介绍广义表的定义、特点和应用场景,讲解广义表的创建、展开和递归操作。
3.数组的运算方法:讲解数组的排序、查找和动态扩容等运算方法。
4.广义表的运算方法:讲解广义表的深度、广度、求表长、求表元素等运算方法。
三、教学方法为了提高教学效果,本节课将采用多种教学方法相结合的方式进行教学。
具体包括以下几种方法:1.讲授法:通过教师的讲解,引导学生了解数组和广义表的基本概念、性质和运算方法。
2.案例分析法:通过分析实际案例,让学生掌握数组和广义表在解决实际问题中的应用。
3.实验法:安排课后的实验环节,让学生亲自动手操作,加深对数组和广义表的理解。
4.讨论法:学生进行小组讨论,促进学生之间的交流与合作,提高解决问题的能力。
四、教学资源为了支持本节课的教学内容和教学方法的实施,我们将准备以下教学资源:1.教材:选用《数据结构与算法》等教材,为学生提供系统的理论知识。
2.参考书:提供《计算机程序设计艺术》等参考书,丰富学生的知识体系。
3.多媒体资料:制作数组和广义表的PPT课件,以直观的方式展示数组和广义表的运算过程。
⼴义表实验报告抽象数据类型的实现1.实验概要实验项⽬名称: 抽象数据类型的实现实验项⽬性质: 设计性实验所属课程名称: 数据结构实验计划学时: 62.实验⽬的对某个具体的抽象数据类型,运⽤课程所学的知识和⽅法,设计合理的数据结构,并在此基础上实现该抽象数据类型的全部基本操作。
通过本设计性实验,检验所学知识和能⼒,发现学习中存在的问题。
进⽽达到熟练地运⽤本课程中的基础知识及技术的⽬的。
3.编译软件Microsoft Visual C++6.04.抽象数据类型定义以及各基本操作的简要描述ADT GList{数据对象:D={i=1,2,...,n>=0;ei (-AtomSet或ei (-GList,AtomSet为某个数据对象} 数据关系:R1={|ei-1,ei (-D,2=基本操作:InitGlist(&L);操作结果:创建空的⼴义表LCreateGList(&L,S);初始条件:S是⼴义表的书写形式串操作结果:由S创建⼴义表LDestroyGlist(&L);初始条件:⼴义表L存在操作结果:销毁⼴义表LCopyGlist(&T,L);初始条件:⼴义表L存在操作结果:由⼴义表L复制得到⼴义表TGListLength(L);初始条件:⼴义表L存在操作结果:求⼴义表L的长度,即元素个数GListDepth(L);初始条件:⼴义表L存在初始条件:⼴义表L存在操作结果:判断⼴义表L是否为空GetHead(L);初始条件:⼴义表L存在操作结果:取⼴义表L的头GList GetTail(L)初始条件:⼴义表L存在操作结果: 取⼴义表L的尾InsertFirst_GL(&L,e)初始条件:⼴义表L存在操作结果:插⼊元素e作为⼴义表L的第⼀元素DeleteFirst_GL(GList &L,&e)初始条件:⼴义表L存在操作结果:删除⼴义表L的第⼀元素,并⽤e返回其值Traverse_GL(GList L,void(*v)(AtomType))初始条件:⼴义表L存在操作结果:遍历⼴义表L,⽤函数Visit处理每个元素} ADT GList5.⼴义表的存储结构-------⼴义表的扩展线性链表存储表⽰------typedef enum{ATOM,LIST}ElemTag; // ATOM==0:原⼦,LIST==1:⼦表typedef struct GLNode{ElemTag tag; // 公共部分,⽤于区分原⼦结点和表结点union // 原⼦结点和表结点的联合部分{AtomType atom; // 原⼦结点的值域struct GLNode *hp; // 表结点的表头指针}a;struct GLNode *tp; // 相当于线性链表的next,指向下⼀个元素结点 }*GList,GLNode;6.主函数及部分函数流程图主函数流程图:由S创建⼴义表L流程图:销毁⼴义表L流程图:求⼴义表L深度流程图:⼴义表L长度流程图:遍历⼴义表L流程图:7.程序清单#include /头⽂件a.h/#include#include#include#include#define TRUE 1 / 函数结果状态代码/ #define FALSE 0#define OK 1#define ERROR 0#define OVERFLOW -2typedef char AtomType;typedef int Status;typedef struct / 串的堆分配存储/{char *ch;int length;}HString;typedef enum{ATOM,LIST}ElemTag; /⼴义表的扩展线性链表存储表⽰/ typedef struct GLNode {ElemTag tag;union{AtomType atom;struct GLNode *tp;}*GList,GLNode;void InitString(HString *T); /函数声明/int StrCompare(HString S,HString T);int StrLength(HString S);Status StrAssign(HString *T,char *chars);Status StrCopy(HString *T,HString S);Status StrEmpty(HString S);Status ClearString(HString *S);Status SubString(HString *Sub, HString S,int pos,int len); Status sever(HString *str,HString *hstr);GList GetHead(GList L);GList GetTail(GList L);void visit(AtomType e);void Traverse_GL(GList L,void(*v)(AtomType));int GListLength(GList L);int GListDepth(GList L);Status InitGList(GList *L);Status CreateGList(GList *L,HString S);Status DestroyGList(GList *L);Status CopyGList(GList *T,GList L);Status GListEmpty(GList L);Status InsertFirst_GL(GList *L,GList e);Status DeleteFirst_GL(GList *L,GList *e);Status StrAssign(HString *T,char *chars) /串的操作/ { /⽣成⼀个其值等于串常量chars的串T / int i,j;if((*T).ch)free((*T).ch); /释放T原有空间/i=strlen(chars);if(!i){(*T).ch=NULL;(*T).length=0;{(*T).ch=(char*)malloc(i*sizeof(char)); /分配串空间/ if(!(*T).ch)exit(OVERFLOW);for(j=0;j(*T).ch[j]=chars[j];(*T).length=i;}return OK;}Status StrCopy(HString *T,HString 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(*T).ch[i]=S.ch[i];(*T).length=S.length;return OK;}Status StrEmpty(HString S){ /若S为空串,则返回TRUE,否则返回FALSE /if(S.length==0&&S.ch==NULL)return TRUE;elsereturn FALSE;}int StrCompare(HString S,HString T){ /若S>T,则返回值>0;若S=T,则返回值=0;若Sfor(i=0;ireturn S.length-T.length;}int StrLength(HString S){ /返回S的元素个数,称为串的长度/return S.length;}Status ClearString(HString *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的⼦串/ 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++)return OK;}void InitString(HString *T){ /产⽣空串/(*T).length=0;(*T).ch=NULL;}Status sever(HString *str,HString *hstr){ /将⾮空串str分割成两部分:hstr为第⼀个','之前的⼦串,str为之后的⼦串/ int n,i=1,k=0; HString ch,c1,c2,c3;InitString(&ch);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);StrCopy(hstr,*str);ClearString(str);}return OK;}Status InitGList(GList *L) /⼴义表的操作/ { /创建空的⼴义表/*L=NULL;return OK;}Status CreateGList(GList *L,HString S) { /由S创建⼴义表/HString emp,sub,hsub;GList p;InitString(&emp);InitString(&sub);InitString(&hsub);StrAssign(&emp,"()");*L=(GList)malloc(sizeof(GLNode));if(!*L)exit(OVERFLOW);if(!StrCompare(S,emp)) /创建空表/{(*L)->tag=LIST;(*L)->a.hp=NULL;(*L)->tp=NULL;}else if(StrLength(S)==1) /创建单原⼦⼴义表/ {(*L)->tag=ATOM;(*L)->a.atom=S.ch[0];(*L)->tp=NULL;(*L)->tag=LIST;(*L)->tp=NULL;SubString(&sub,S,2,StrLength(S)-2); /脱外层括号/sever(&sub,&hsub); / 从sub中分离出表头串hsub / CreateGList(&(*L)->a.hp,hsub); p=(*L)->a.hp;while(!StrEmpty(sub)) /表尾不空,则重复建n个⼦表/{sever(&sub,&hsub);CreateGList(&p->tp,hsub);p=p->tp;};}return OK;}Status DestroyGList(GList *L){ /销毁⼴义表/GList ph,pt;if(*L) /L不为空表/{if((*L)->tag) /当L是⼦表/ph=(*L)->a.hp;else /当L是原⼦/ph=NULL;pt=(*L)->tp;free(*L); /释放L所指结点/*L=NULL;DestroyGList(&ph); /递归销毁表ph /DestroyGList(&pt); /递归销毁表pt /}return OK;}Status CopyGList(GList *T,GList L)*T=NULL;return OK;}*T=(GList)malloc(sizeof(GLNode));if(!*T)exit(OVERFLOW);(*T)->tag=L->tag;if(L->tag==ATOM) /复制共⽤体部分/(*T)->a.atom=L->a.atom; /复制单原⼦/ elseCopyGList(&(*T)->a.hp,L->a.hp); /复制⼦表/ if(L->tp==NULL)(*T)->tp=L->tp;elseCopyGList(&(*T)->tp,L->tp); /复制⼦表/ return OK;}int GListLength(GList L){ /求⼴义表L的长度/int len=0;GList p;if(L->tag==LIST&&!L->a.hp) /空表/return 0;else if(L->tag==ATOM) /单原⼦表/return 1;else /⼀般表/{p=L->a.hp;do{len++;p=p->tp;}while(p);}int GListDepth(GList L){ /求⼴义表L的深度/int max,dep;GList pp;if(L==NULL||L->tag==LIST&&!L->a.hp)return 1; /空表深度为1/else if(L->tag==ATOM)return 0; /单原⼦表深度为0 /else /求⼀般表的深度/for(max=0,pp=L->a.hp;pp;pp=pp->tp){dep=GListDepth(pp);if(dep>max)max=dep;}return max+1; /⾮空表的深度是各元素的深度的最⼤值加1 / } Status GListEmpty(GList L){ /判定⼴义表L是否为空/if(!L||L->tag==LIST&&!L->a.hp)return OK;elsereturn ERROR;}GList GetHead(GList L){ /取⼴义表表头/GList h;InitGList(&h);if(!L||L->tag==LIST&&!L->a.hp){printf("\n空表⽆表头!");exit(0);}exit(OVERFLOW);h->tag=L->a.hp->tag;h->tp=NULL;if(h->tag==ATOM)h->a.atom=L->a.hp->a.atom;elseCopyGList(&h->a.hp,L->a.hp->a.hp);return h;}GList GetTail(GList L){ /取⼴义表表尾/GList T;if(!L){printf("\n空表⽆表尾!");exit(0);}T=(GList)malloc(sizeof(GLNode));if(!T)exit(OVERFLOW);T->tag=LIST;T->tp=NULL;CopyGList(&T->a.hp,L->a.hp->tp);return T;}Status InsertFirst_GL(GList *L,GList e){ /插⼊元素e作为⼴义表L的第⼀元素/ GList p=(*L)->a.hp; (*L)->a.hp=e;e->tp=p;return OK;}Status DeleteFirst_GL(GList *L,GList *e){ /删除⼴义表L的第⼀元素,并⽤e返回其值/ if(*L)(*L)->a.hp=(*e)->tp;(*e)->tp=NULL;}else*e=*L;return OK;}void Traverse_GL(GList L,void(*v)(AtomType)) { /遍历⼴义表/GList hp;if(L){if(L->tag==ATOM) /L是原⼦/{v(L->a.atom);hp=NULL;}else /L是⼦表/hp=L->a.hp;Traverse_GL(hp,v);Traverse_GL(L->tp,v);}}void visit(AtomType e){printf("%c ", e);}void main() /主函数/{char p[80];GList l,m;HString t;InitString(&t);Status Eflag;int x;int d;do{E flag=TRUE;d o{system("cls");printf("\n***************************************************"); printf("\n1:建⽴空⼴义表");printf("\n2:由字符串建⽴⼴义表");printf("\n3:退出");printf("\n***************************************************"); printf("\n请选择功能:");scanf("%d",&x);switch(x){case 1: if(InitGList(&l)){printf("\n建表成功!");getch();}else{printf("\n建表失败!");getch();Eflag=FALSE;}break;case 2: printf("\n请输⼊合法的⼴义表书写形式"); printf("\n格式如:(),(a,b),(a,(),b),(a,(c,d),f)");printf("\n输⼊字符串:");if(CreateGList(&l,t)){printf("\n建表成功!");getch();}else{printf("\n建表失败!");getch();Eflag=FALSE;}break;case 3: printf("\n感谢使⽤本软件!");getch();exit(0);default: printf("\n输⼊错误!请重新输⼊!");getch();}}w hile(x!=1&&x!=2||!Eflag);d o{Status Eflag=TRUE;system("cls");printf("\n***************************************************"); printf("\n1:复制⼴义表");printf("\n2:求⼴义表长度");printf("\n3:求⼴义表深度");printf("\n4:判断⼴义表是不是空表");printf("\n5:取⼴义表表头");printf("\n6:取⼴义表表尾");printf("\n7:头结点插⼊元素");printf("\n8:删除第⼀个元素");printf("\n11:退出");printf("\n***************************************************"); printf("\n请选择功能:");printf("\n请输⼊你要选择的功能:");scanf("%d",&x);switch(x){case 1: if(CopyGList(&m,l)){printf("\n复制成功!");getch();}break;。
广义表的应用课程设计一、教学目标本节课的教学目标是让学生掌握广义表的基本概念及其应用。
知识目标包括:了解广义表的定义、结构及特点;掌握广义表的创建、删除和遍历方法;理解广义表在计算机科学中的应用。
技能目标包括:能够运用广义表解决实际问题;能够使用编程语言实现广义表的相关操作。
情感态度价值观目标包括:培养学生对计算机科学的兴趣;培养学生团队合作、积极思考的能力。
二、教学内容本节课的教学内容主要包括广义表的基本概念、创建与删除方法、遍历方法以及广义表在计算机科学中的应用。
首先,介绍广义表的定义和特点,让学生了解广义表与普通列表的区别;其次,讲解广义表的创建与删除方法,让学生掌握如何操作广义表;然后,介绍广义表的遍历方法,让学生学会如何遍历广义表;最后,通过实例讲解广义表在计算机科学中的应用,让学生了解广义表的实际价值。
三、教学方法为了达到本节课的教学目标,将采用讲授法、案例分析法和讨论法等多种教学方法。
首先,通过讲授法向学生传授广义表的基本概念及其应用;其次,通过案例分析法让学生深入了解广义表的实际价值;最后,通过讨论法激发学生的思考,培养学生的团队合作能力。
四、教学资源本节课的教学资源包括教材、多媒体资料和实验设备。
教材为学生提供了广义表的基本概念、创建与删除方法、遍历方法以及应用实例;多媒体资料为学生提供了丰富的视觉感受,帮助学生更好地理解广义表的相关概念;实验设备则为学生提供了动手实践的机会,让学生在实际操作中掌握广义表的相关方法。
五、教学评估本节课的教学评估将采用多元化的评价方式,包括平时表现、作业、小测验和期末考试。
平时表现占20%,主要评估学生的课堂参与度和团队合作能力;作业占30%,主要评估学生对广义表知识的掌握程度;小测验占20%,主要评估学生的即时理解和应用能力;期末考试占30%,主要评估学生对广义表知识的全面理解和应用能力。
评估标准将严格按照课程目标和教材内容制定,确保评估的客观性和公正性。
广义表的应用课程设计一、课程目标知识目标:1. 理解广义表的定义和基本概念;2. 学会使用广义表表示复杂的线性结构;3. 掌握广义表的基本操作,如创建、插入、删除、查找等;4. 能够运用广义表解决实际问题。
技能目标:1. 能够运用广义表的基本操作,实现线性结构的存储和运算;2. 能够分析实际问题,选择合适的广义表结构进行建模;3. 能够编写简单的程序,利用广义表解决具体问题;4. 培养学生的逻辑思维能力和编程实践能力。
情感态度价值观目标:1. 培养学生对数据结构和算法的兴趣,激发学习热情;2. 培养学生的团队协作意识和解决问题的能力;3. 培养学生面对复杂问题,勇于尝试、积极探究的精神;4. 增强学生的自信心和成就感,鼓励他们发挥创新精神。
课程性质:本课程为计算机科学领域的数据结构与算法课程,旨在帮助学生掌握广义表这一数据结构,并运用其解决实际问题。
学生特点:学生具备一定的编程基础,对数据结构有一定了解,但可能对广义表的认识较为陌生。
教学要求:结合学生特点,注重理论与实践相结合,通过实例讲解、课堂互动、上机实践等环节,使学生掌握广义表的应用。
同时,关注学生的情感态度,激发学习兴趣,培养其解决问题的能力和团队协作精神。
在教学过程中,将课程目标分解为具体的学习成果,以便于教学设计和评估。
二、教学内容1. 广义表的定义与基本概念:- 线性表、广义表的概念与区别;- 广义表的元素、表头、表尾及表长等基本概念。
2. 广义表的存储结构:- 顺序存储结构;- 链式存储结构。
3. 广义表的基本操作:- 创建广义表;- 插入、删除、查找等操作;- 广义表的遍历。
4. 广义表的应用:- 利用广义表解决实际问题,如多项式的表示与运算;- 广义表在数据压缩中的应用;- 广义表在计算机图形学中的应用。
5. 教学案例与上机实践:- 结合实际案例,分析广义表的应用场景;- 上机实践,编写程序实现广义表的基本操作;- 团队协作,共同探讨广义表在解决复杂问题中的应用。
沈阳航空航天大学课程设计报告课程设计名称:数据结构课程设计课程设计题目:识别广义表头尾演示院(系):计算机学院专业:软件工程班级:34010301学号:2013040103030姓名:张为指导教师:丁一军说明:结论(优秀、良好、中等、及格、不及格)作为相关教环节考核必要依据;格式不符合要求、数据不实,不予通过。
报告和电子数据必须作为实验现象重复的关键依据。
学术诚信声明本人声明:所呈交的报告(含电子版及数据文件)是我个人在导师指导下独立进行设计工作及取得的研究结果。
尽我所知,除了文中特别加以标注或致谢中所罗列的内容以外,报告中不包含其他人己经发表或撰写过的研究结果,也不包含其它教育机构使用过的材料。
与我一同工作的同学对本研究所做的任何贡献均己在报告中做了明确的说明并表示了谢意。
报告资料及实验数据若有不实之处,本人愿意接受本教学环节“不及格”和“重修或重做”的评分结论并承担相关一切后果。
本人签名: 日期:年月日沈阳航空航天大学课程设计任务书目录沈阳航空航天大学 (I)学术诚信声明 (I)1 题目介绍与功能描述 (1)1.1题目介绍 (1)1.2具体要求 (1)1.3题目分析 (1)2 系统功能模块结构图 (2)2.1系统功能结构图 (2)2.2主要模块功能说明 (3)2.2.1 建立广义表 (3)2.2.2 对表进行求头尾操作 (3)3 数据结构设计及用法说明 (4)3.1存储结构 (4)3.2用法说明 (4)4 主要函数 (5)4.1 VOID CREATLIST(GL IST &L S ) (5)4.2 VOID GL_E LEM(GL IST P) (7)4.3 VOID PRINTF_GL(GL IST L S,INT &I) (7)4.4 VOID G ET H EAD(GL IST &L S) (9)4.5 VOID G ET T AIL(GL IST &L S) (9)4.6 VOID G ET_HT(GL IST L S) (10)5 主要函数流程图 (12)5.1 MAIN函数 (12)5.2 CREATLIST函数 (13)5.3 PRINTF_GL函数 (14)6 调试报告 (15)6.1测试用例设计 (15)6.2调试过程 (15)6.3运行结果 (16)参考文献 (21)附录源程序清单 (22)1 题目介绍与功能描述1.1 题目介绍本课程设计主要完成对广义表的建立以及遍历(输出),并且对已建立的广义表实施操作,操作序列为一串由“t”、“h”以及“”组成的字符串。
“t”表示对广义表求表尾,“h”表示对广义表求表头,“”表示遍历当前整个广义表。
1.2 具体要求1.写一个程序,建立广义表的存储结构,演示在此存储结构上实现的广义表求头/求尾操作序列的结果。
2.广义表允许多行输入,其中可以任意输入空格符;3.广义表存储结构自定;4.对广义表的操作为一个由t和h组成的字符串;1.3 题目分析设计一个广义表允许分多行输入,其中可以任意地输入空格符,原子是不限长的仅由字母或数字组成的串。
广义表采用如教科书中图5.8所示结点的存储结构,按表头和表尾的分解方法编写建立广义表存储结构的算法。
对已建立存储结构的广义表施行操作,操作序列为一个仅由“t”(取表尾)或“h”(取表头)组成的串,它可以是空串(此时印出整个广义表),自左至右施行各种操作,再以符号形式显示结果。
程序先进行广义表的输入,由程序进行广义表的建立,在打印出来,可检验广义表是否正确的建立。
然后进行求头尾的操作序列的输入。
由程序进行对广义表进行求头尾的操作。
程序中应该多次运用递归的思想,可以使程序显得更加的简洁高效。
2 系统功能模块结构图2.1 系统功能结构图图2.1 系统功能结构图2.2 主要模块功能说明2.2.1 建立广义表建立广义表由函数void creatlist(GList &Ls)完成。
当用户完成对广义表的输入后,由此函数完成对广义表的建立。
此函数运用递归的思想可以对广义表进行任意地建立。
能够输入空格字符,建立为空的广义表。
广义表的节点可以为原子,也可以为广义表,能够进行循环的建立直到输入完成,或程序结束。
2.2.2 对表进行求头尾操作对广义表进行求头尾操作是由多个函数共同完成,分别是void GetTail(GList &L void GetHead(GList &Ls),void Get_HT(GList Ls),void GL_Elem(GList p) void printf_GL(GList Ls,int &i)。
当输入一串由t和h组成的操作序列后,由函数void Get_HT(GList Ls),对求头尾进行函数的调用。
如果是求头则调用GetHead(GList &Ls),如果是求尾则调用void GetTail(GList &Ls),而函数void GL_Elem(GList p)是负责对广义表的原子节点进行输出,函数void printf_GL(GList Ls,int &i)负责对广义表进行整个的输出。
3 数据结构设计及用法说明3.1 存储结构广义表的存储结构采用的是链式存储结构,每个数据元素可用一个节点表示。
由于列表中的数据元素可能为原子或列表,由此需要两种结点:原子结点和表结点。
前者用于表示原子,后者用于表示列表,一个表结点可由3个域组成:标志域、指示表头的指针域和指示表尾的指针域;而原子结点只需要两个域:标志域和值域。
广义表的存储结构定义形式为:typedef struct GLNode //广义表节点{int tag; //表结点类型(tag=0表示原子结点,tag=1表示表结点)union{char data;struct{ struct GLNode *hr,*tr;};};}*GList;3.2 用法说明对广义表的结构采用链表的形式进行定义,由于广义表可以是原子也可以是表,所以在结构体中还采用了共用体的数据结构。
让原子和节点可以共享存储单元。
tag代表节点的类型0为原子,1为表。
hr代表表的头指针,tr代表表的尾指针。
data为表的内容。
4 主要函数程序主体由几个关键函数组成:creatlist(GList &Ls )、GL_Elem(GList p)、printf_GL(GList Ls,int &i)、GetHead(GList &Ls)、GetTail(GList &Ls)、Get_HT(GList Ls)以及main()函数中的三个部分,下面将对这些函数一一介绍。
4.1 void creatlist(GList &Ls )单独的creatlist()函数并不能创建完整的广义表,需要与main( )函数中的第一部分相结合才能共同完成广义表的创建。
creatlist()在main中的调用如下:char c;c=getchar();if(c!='(')return -1,// 广义表第一个字符必须是'(',否则终止函数GList Ls;creatlist(Ls);在整个程序中采用getchar( )函数从键盘缓冲区读取输入的广义表数据。
creatlist( )函数的完全代码如下:void creatlist(GList &Ls ) //建广义表{ char c;c=getchar(); //拾取一个合法字符if(c==' ') //空表的情况{Ls=NULL;c=getchar();if(c!=')') return; //空表的下一个合法字符应该是')'}else{ //当前输入的广义表非空GList p;Ls=(GList)malloc(sizeof(GLNode));Ls->tag =1; //表结点if(c!='(') //表头为单原子{Ls->hr=(GList)malloc(sizeof(GLNode));p=Ls->hr;p->tag =0;p->data=c; //建立原子结点}else{ // 表头为广义表creatlist(Ls->hr); // 对此广义表递归建立存储结构}c=getchar();if (c==',')creatlist(Ls->tr); //当前广义表未结束,等待输入下一个子表else if(c==')')Ls->tr =NULL; //当前广义表输入结束}}广义表是采用递归的方式定义的,因此creatlist()中广义表也是采用递归的方式建立的。
由于广义表的第一个字符“(”在main()函数中已被读取,因此creatlist()中从键盘数据缓冲区读取的第一个字符是所输入的广义表的第二个字符。
若当层广义表非空,则应建立表结点。
在建立原子结点时所用的判断方法为if(c!=’(’) 是因为“,”之后的字符要么是“(”,要么是原子。
在经过代码:if(c==',') creatlist(Ls->tr); ,递归建立的广义表的读取的第一个字符只能是原子或者“(”,而不可能是“,”,因此建立原子结点的判断方法为if(c!=’(’)。
当getchar( )读取的字符为“(”时,表示要进入下一层广义表,故使用语句creatlist(Ls->hr); 递归建立下一层广义表。
当getchar( )读取的字符为“,”时,表示当层广义表未结束,还有子表需要建立,故用creatlist(Ls->tr); 递归建立剩余的子表。
当getchar( )读取的字符为“)”时,表示当层广义表已结束,则表结点的表尾指针应为空,即Ls->tr =NULL;缺点:函数creatlist( )的纠错能力较差,要求输入的广义表应为广义表的标准正确形式,如(a,b,(a,1,(d,3,4))) ,如果输入的形式错误,如:(s,d(,o)) 就会造成整个程序无法运行下去。
4.2 void GL_Elem(GList p)GL_Elem( )十分简单,只是一个将存储的原子输出的函数,代码如下:void GL_Elem(GList p) // 输出原子{printf("%c",p->data) ;}4.3 void printf_GL(GList Ls,int &i)这是输出广义表的函数,同creatlist( )函数一样,printf_GL( )并不能单独输出完整的已存储的广义表,它需要与main( )函数中的第二部分相结合才能共同完成广义表的输出。