1、数据结构实验报告实验题目: 广义表的创建与遍历实验目的:熟悉和掌握广义表的定义及结构, 可以创建及遍历广义表。实验内容:利用栈创建以及遍历一个广义表。一、需求分析1.本演示程序中,输入广义表的内容应为任意符合广义表要求结构的数据,将数据输入创建广义表中,再通过遍历程序将其以广义表形式输出。2.本程序是以用户与计算机的对话方式执行,运行程序后,按要求输入数据即可。3.程序执行的命令包括:(1)构造广义表与链栈,并初始化(2)输入广义表(3)输出广义表(4)结束4.测试数据:输入(),(a,b),(c,d) 输出(),(a,b),(c,d)错误输入:如果输入(),(a,b),(c,d) 输出(),
2、(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 nodechar data
3、; /*存储数据*/int tag; /*用以标记,标记为 1 时为左括号,标记为 0 时为字符,标记为-1 时为新开辟节点*/struct node *hp; /*该指针指向字表*/struct node *tp; /*该指针指向后续节点*/node;/定义链栈typedef struct Snodenode *data;struct Snode *next;Snode;Snode *topnode *inputSnode *sSnode *p;node *outputnode *p,*q,*head;2.每个模块的分析:(1) 主程序模块:int main()node *head;prin
4、tf(“请输入广义表: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; /
5、*广义表形式第一个字符必为左括号*/scanf(“%c“, /*输入字符*/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“,
6、/*接着输入数据*/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(n
7、ode); /*申请新节点,标记-1*/q-tag=-1;p-tp=q; /*新节点链到当前节点后续节点*/p=p-tp; /*移动指针到当前节点的后续*/else if(x=) /*遇到右括号*/p-tp=NULL; /*后续域置空*/top=Pop(top, /*栈顶指针退栈*/else /*遇到其他字符*/p-tag=0; /*标记为 0*/p-data=x; /*数据域存数据*/p-hp=NULL; /*子表指向置空*/scanf(“%c“, /*再读下一个字符*/p-tp=NULL; /*循环结束,当前节点后续置空*/return(head);(3) 广义表的遍历:void prin
8、t(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;el
9、se if(p-tag=-1) /*标记为-1,先出栈,出栈后 p 上移输出右括号,如果后续不空,输出逗号*/top=Pop(top,printf(“)“);if(p-tp!=NULL)printf(“,“);p=p-tp;else /*若 p 空,表示该层结束*/top=Pop(top, /*退栈,指针上移,若上移后仍不为空,且此时栈必定不空,输出右括号*/printf(“)“);if(p-tp!=NULL) /*若后续不为空,需输出逗号,指针后移*/printf(“,“);p=p-tp;printf(“n“);(4) 入栈模块:Snode *Push(Snode *top,node *in
10、put)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);(6)函数调用关系图3完整的程序:(见源文件).四 使用说明、测试分析及结果1.程序使用说明:(1)本程
11、序的运行环境为 VC6.0。(2)进入演示程序后即显示提示信息:请输入广义表:输入数据该广义表为:输出广义表2.测试结果:输入(),(a,b),(c,d) 输出(),(a,b),(c,d)错误输入:如果输入(),(a,b),(c,d) 输出(),(a,b),(c,d)3. 运行界面:输入(),(a,b),(c,d) 输出(),(a,b),(c,d)int main()Snode *Push(Snode *top,node *input)node *create()void print(node *head) Snode *Pop(Snode *top,node *output)错误输入:如果输
12、入(),(a,b),(c,d) 输出(),(a,b),(c,d)五、实验总结本次编程我首先思考了广义表建立的算法,并借鉴了网上一些算法,完善了自己的算法,然后在纸上写了自己的程序主体,中间进栈遇到了一些问题,当时没有考虑到设定全局变量,导致无法进栈,后来编程课中在同学的帮助下解决了栈的问题,基本再没有遇到问题,程序完美运行,通过这次试验,我对于广义表的理解更加深了一层,更熟悉广义表及栈。教师评语:实验成绩:#include#include#define maxsize 100/定义广义表typedef struct nodechar data; /*存储数据*/int tag; /*用以标记,
13、标记为 1 时为左括号,标记为 0 时为字符,标记为-1 时为新开辟节点*/struct node *hp; /*该指针指向字表*/struct node *tp; /*该指针指向后续节点*/node;/定义链栈typedef struct Snodenode *data;struct Snode *next;Snode;/ 入栈Snode *Push(Snode *top,node *input)Snode *s;s=(Snode *)malloc(sizeof(Snode); /*申请新节点*/s-data=input;s-next=top;top=s;return(top);/ 出栈函数
14、 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);/广义表输入node *create() node *p,*q,*head; /*指针 p 是一个移动指针,指针 q 用以开辟新节点,head 为头指针*/char x; /*输入字符*/Snode *top; /*栈顶指针*/top=NULL; /*栈顶置空*/q=(node *)malloc(sizeof(n
15、ode); /*申请新节点*/q-tag=1; /*广义表形式第一个字符必为左括号*/scanf(“%c“, /*输入字符*/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; /*活动
16、指针移到当前节点的子表*/scanf(“%c“, /*接着输入数据*/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=,) /*遇到逗号*/
17、q=(node *)malloc(sizeof(node); /*申请新节点,标记-1*/q-tag=-1;p-tp=q; /*新节点链到当前节点后续节点*/p=p-tp; /*移动指针到当前节点的后续*/else if(x=) /*遇到右括号*/p-tp=NULL; /*后续域置空*/top=Pop(top, /*栈顶指针退栈*/else /*遇到其他字符*/p-tag=0; /*标记为 0*/p-data=x; /*数据域存数据*/p-hp=NULL; /*子表指向置空*/scanf(“%c“, /*再读下一个字符*/p-tp=NULL; /*循环结束,当前节点后续置空*/return(h
18、ead);/广义表输出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) p
19、rintf(“,“);p=p-tp;else if(p-tag=-1) /*标记为-1,先出栈,出栈后 p 上移输出右括号,如果后续不空,输出逗号*/top=Pop(top,printf(“)“);if(p-tp!=NULL)printf(“,“);p=p-tp;else /*若 p 空,表示该层结束*/top=Pop(top, /*退栈,指针上移,若上移后仍不为空,且此时栈必定不空,输出右括号*/printf(“)“);if(p-tp!=NULL) /*若后续不为空,需输出逗号,指针后移*/printf(“,“);p=p-tp;printf(“n“);int main()node *head;printf(“请输入广义表:n“);head=create();printf(“该广义表为:n“);print(head);getchar();getchar();return 0;