当前位置:文档之家› 哈工大数据结构线性结构及其应用

哈工大数据结构线性结构及其应用

哈尔滨工业大学计算机科学与技术学院实验报告课程名称:数据结构课程类型:必修实验项目名称:线性结构及其应用实验题目:线性结构及其应用一、实验目的二、实验要求及实验环境三、设计思想(本程序中的用到的所有数据类型的定义,主程序的流程图及各程序模块之间的调用关系)1.逻辑设计2.物理设计四、测试结果五、系统不足与经验体会六、附录:源代码(带注释)一、实验目的输入中缀表达式保存并显示,之后转换为后缀表达式,并且求出表达式的结果。

二、实验要求及实验环境实验要求(1)从键盘输入任意一个语法正确的(中缀)表达式,显示并保存该表达式。

(2)利用栈结构,把上述(中缀)表达式转换成后缀表达式,并显示栈的状态变化过程和所得到的后缀表达式。

(3)利用栈结构,对上述后缀表达式进行求值,并显示栈的状态变化过程和最终结果。

实验环境Dev-C++软件中运行Win7系统三、设计思想本实验中定义了int 型,char型,struct 型,char *型,struct型逻辑设计:应用栈后进先出的规律,在转换为后缀表达式时,将操作运算符压入栈中,碰见更高级运算符时栈中元素出栈,继续比较;否则压栈。

这样可以完成表达式的转换。

在利用得到的后缀表达式计算结果时,将操作数压栈,遇见符号直接计算,这是后缀表达式的特点。

物理设计:建立一个结构体数组的栈,数组中存放运算符。

数组的添加和减少都在数组末尾元素进行。

可以视为一个栈。

四、测试结果样例1. 输入1+2*(3-4/2)输出为1+2*(3-4/2) ->此为保存并输出的中缀表达式12342/-*+ ->此为输出后缀表达式3 ->此为表达式的值样例2. 输入1+2*3/4-5输出为1+2*3/4-5123*4/+5--3五、系统不足与经验体会不足1.此程序只能进行整形一位数上的计算,无法实现实数范围内的计算。

2.程序用的是结构体数组来表示栈的存储结构,数组定义时,定义一段很大的空间,导致空间利用率不高。

经验体会1.建立算法框架时如中缀表达式变后缀表达式,后缀表达式的求值时,需要用到很多的函数来搭建。

这个可以先放下,先将该算法编好,完成之后再将所需要的函数填补起来。

这样可以简化步骤。

2.算法分模块解决,不把所有算法堆到一个函数里面。

这样可以使程序简洁明了,各个函数的分工明确。

易于调试差错。

六、附录:源代码(带注释)#include<stdio.h>#include<stdlib.h>#define MAX 100 //定义栈中最多有100个元素/*创建结构体,结构体中含有两个量,一个数组栈,一个指向栈顶元素*/ typedef struct{int data[MAX]; //定义数组栈int top; //栈顶标号}seqstack,*pseqstack;/*创建一个顺序栈,入口无参数,返回一个指向顺序栈的指针*/pseqstack init_seqstack(){pseqstack s;s=(pseqstack)malloc(sizeof(seqstack)); //申请栈的内存空间 if(s)s->top=-1; //创建新栈时栈顶指针指向-1return s;}/*判断栈是否为空,返回1表示空,0表示非空*/int empty_seqstack(pseqstack s){if(s->top==-1) //判断条件为top指针是否指向-1return 1;elsereturn 0;}/*入栈:栈顶插入x*/int push_seqstack(pseqstack s,int x){if(s->top==MAX-1)return 0; //栈已满,返回0else{s->top++; //栈顶指针+1,指向将要压栈的xs->data[s->top]=x;return 1;}}/*出栈:入口参数为s,*x。

删除栈顶元素,并且保存在*x中*/int pop_seqstack(pseqstack s,char *x)if(empty_seqstack(s))return 0;else{*x=s->data[s->top];s->top--;return 1;}}/*销毁栈*/void destroy_seqstack(pseqstack *s){if(*s)free(*s);*s=NULL;}/*判断字符是否为操作数;是返回1,否则为0*/int isnum(char c){if(c>='0'&&c<='9')return 1; //若字符常量的值小于等于‘9’大于等于‘0’则为操作数,并返回1 elsereturn 0;}/*求算符的优先级,入口参数为字符op*/int priority(char op){switch(op){case '\0': return (0);case ')': return (1);case '+': return (2);case '-': return (2);case '*': return (3);case '/': return (3);case '(': return (4);default: return (5);//定义各个支付对应的优先级}/*中缀表达式转换成后缀表达式,入口参数字符指针*in,*post*///*post中存入后缀表达式void change(char *in,char *post){pseqstack s;char c,w,y;int z1,z2;s=init_seqstack();if(!s){printf("initial fault");} //栈初始化失败输出initial fault push_seqstack(s,'\0'); /*转换之前将栈底存入‘\0’,标记作用,便于判断循环中是否到栈底*/w=*in; //w存入中缀表达式中第一个元素while(s->data[s->top]!='\0'||w!='\0') /*当s栈栈底元素不为‘\0’或者w不为‘\0’(w为\0时表示中缀表达式已经读完)时循环*/{if(isnum(w)){*post=w;post++;w=*(++in);} /*判断w是操作数时,将w赋给*post,并且指针post++,w中值被赋为*in中下一个元素*///w不是操作数时else{if(s->data[s->top]=='('&&w==')'){pop_seqstack(s,&y);w=*(++in);}/*栈顶为‘(‘且w为’)‘时栈顶元素出栈,但出栈元素’(‘不存入*post,w中值被赋为*in 中下一个元素*/else{/*比较栈顶元素与w运算符的优先级大小,若栈顶优先级更小,则w入栈否则栈顶出栈,并将出栈元素赋给*post,post++ */if(s->data[s->top]=='('||priority(s->data[s->top])<priority(w)) {push_seqstack(s,w);w=*(++in);}else{pop_seqstack(s,&y);*post=y;post++;}}}}*post='\0'; //字符串最后添加‘\0‘表示字符串终止destroy_seqstack(&s); //销毁栈}/*后缀表达式求值,入口参数为字符指针*b,其中存储了后缀表达式*/void result(char *b){pseqstack s;char ch,a,c,d,result;ch=*b++;s=init_seqstack();//循环在后缀表达式到结尾‘\0‘时终止while(ch!='\0'){if(isnum(ch)){push_seqstack(s,ch-'0');}//若ch 为操作数则存入栈中,否则进行运算else{pop_seqstack(s,&a);pop_seqstack(s,&c); //栈中最上方的两个数出栈计算switch(ch) //各种条件下的运算{case '+': d=a+c; break;case '-': d=c-a; break;case '*': d=a*c; break;case '/': d=c/a; break;}push_seqstack(s,d); //运算后的结果再压入栈中 }ch=*b++;}//循环完成后栈顶元素就是表达式最后的值,输出该值printf("%d",s->data[s->top]);destroy_seqstack(&s);}/*主函数*/int main(){int x,y;char a[MAX],b[MAX];gets(a); //输入中缀表达式,并且存入字符数组a[MAX]中puts(a); //输出保存得到的中缀表达式change(a,b); //调用函数得到后缀表达式puts(b); //输出后缀表达式result(b); //调用函数计算表达式的值,并输出该值getchar();getchar();return 0;}。

相关主题