数据结构栈和队列的应用表达式的求值

数据结构栈和队列的应用表达式的求值
数据结构栈和队列的应用表达式的求值

2011-2012学年第一学期

数据结构课内实验报告

实验名:栈和队列的应用:表达式的求值

姓名:

学号:

班级:

指导老师:

日期:

实验题目:

1、实验目的:

通过此实验进一步理解栈和队列,提高运用理论解决实际问题的能力。2、实验内容:

例如,输入9-(2+4*7)/5+3# ,并按回车键,即可输出结果如下:

表达式的运算结果是:6

表达式的后缀表达式为:9 2 4 7 * +5/-3+

3、数据结构及算法思想:

表达式计算是实现程序设计逻辑语言的基本问题之一,也是栈和队列应用的一个典型的例子。该设计是先通过栈将中缀表达式转换为后缀表达式,在转换过程中又用到了队列的操作。而在得到后缀表达式之后,又用到队列的操作对生成的后缀表达式进行计算。在整个设计的实现过程中,用到的都是栈和队列的概念。

4、模块化分:

本程序分为2个模块:

(1)中缀表达式转换为后缀表达式;

(2)求后缀表达式

5、详细设计及运行结果:

(1)中缀表达式转换为后缀表达式

void CTPostExp(SeqQueue *Q){

SeqStack S; //运算符栈

char c,t;

InitStack(&S); //初始化栈

Push(&S,'#'); //压入栈底元素‘#’

do { //扫描中缀表达式

c=getchar();

switch(c){

case ' ':break; //去除空格符

case '0':

case '1':

case '2':

case '3':

case '4':

case '5':

case '6':

case '7':

case '8':

case '9': EnQueue(Q,c);break;

case '(':Push(&S,c);break;

case ')':

case '#':

do{

t=Pop(&S);

if(t!='('&&t!='#') EnQueue(Q,t);

}while(t!='('&&S.top !=-1);break;

case '+':

case '-':

case '*':

case '/':

while(Priority(c)<=Priority(GetTop(S))){

t=Pop(&S);EnQueue(Q,t);

}

Push(&S,c);break;

}

}while(c!='#'); //以'#'号结束表达式扫描}

(2)后缀表达式的计算

DataType CPostExp(SeqQueue Q) {

SeqStack S;

char ch;

int x,y;

InitStack(&S);

while(!QueueEmpty(Q)){

ch=DeQueue(&Q);

if(ch>='0' &&ch<='9')

Push(&S,ch);

else{

y=Pop(&S)-'0';

x=Pop(&S)-'0';

switch(ch){

case '+':Push(&S,(char)(x+y+'0'));break;

case '-':Push(&S,(char)(x-y+'0'));break;

case '*':Push(&S,(char)(x*y+'0'));break;

case '/':Push(&S,(char)(x/y+'0'));break;

}

}

}

return GetTop(S);

}

输入9-(2+4*7)/5+3# ,并按回车键,

输出:表达式的运算结果是:6

表达式的后缀表达式为:9 2 4 7 * +5/-3

6、调试情况,设计技巧及体会:

表达式是由运算对象、运算符、括号组成的有意义的式子。要写此程序,必须了解到底什么是中缀表达式、后缀表达式并灵活运用栈和队列。

7、源程序清单:

#include

#define StackSize 100

#define QueueSize 100

/*队列的相关操作*/

typedef char DataType;

typedef struct{

char data[100];

int front,rear;

}SeqQueue; //定义队列类型

void InitQueue(SeqQueue *Q) { //初始化队列

Q->front =0;

Q->rear =0;

}

int QueueEmpty(SeqQueue Q) { //判空队列return Q.rear ==Q.front ;

}

void EnQueue(SeqQueue *Q,DataType x) { //入队列

if((Q->rear +1) % QueueSize==Q->front )

printf("Queue overflow");

else{

Q->data[Q->rear]=x;

Q->rear =(Q->rear +1)%QueueSize;

}

}

DataType DeQueue(SeqQueue *Q) {

char x;

if(QueueEmpty(*Q)) return 0;

else{

x=Q->data[Q->front ];

Q->front =(Q->front +1)%QueueSize;

return x;

}

} /*栈的相关操作*/

typedef struct{

DataType data[100];

int top;

}SeqStack; //栈类型的定义void InitStack(SeqStack *S) { //初始化栈

S->top =-1;

}

void Push(SeqStack *S,DataType x) { //入栈if(S->top ==StackSize-1)

printf("Stack ouerflow");

else{

S->top =S->top +1;

S->data [S->top ]=x;

}

}

DataType Pop(SeqStack *S) { //出栈

if(S->top ==-1) {

printf("stack underflow");

return 0;

}

else

return S->data[S->top --];

}

DataType GetTop(SeqStack S) {

//取栈顶元素

if(S.top ==-1) {

printf("stack empty");

return 0;

}

else

return S.data [S.top ];

} //求运算符优先级函数

int Priority(DataType op) {

switch(op){

case '(':

case '#':return 0;

case '-':

case '+':return 1;

case '*':

case '/':return 2;

}

return -1;

}

void CTPostExp(SeqQueue *Q){

SeqStack S; //运算符栈

char c,t;

InitStack(&S); //初始化栈

Push(&S,'#'); //压入栈底元素‘#’

do { //扫描中缀表达式

c=getchar();

switch(c){

case ' ':break; //去除空格符

case '0':

case '1':

case '2':

case '3':

case '4':

case '5':

case '6':

case '7':

case '8':

case '9': EnQueue(Q,c);break; case '(':Push(&S,c);break;

case ')':

case '#':

do{

t=Pop(&S);

if(t!='('&&t!='#') EnQueue(Q,t);

}while(t!='('&&S.top !=-1);break;

case '+':

case '-':

case '*':

case '/':

while(Priority(c)<=Priority(GetTop(S))){

t=Pop(&S);EnQueue(Q,t);

}

Push(&S,c);break;

}

}while(c!='#'); //以'#'号结束表达式扫描

} //后缀表达式的计算

DataType CPostExp(SeqQueue Q){

SeqStack S;

char ch;

int x,y;

InitStack(&S);

while(!QueueEmpty(Q)){

ch=DeQueue(&Q);

if(ch>='0' &&ch<='9')

Push(&S,ch);

else{

y=Pop(&S)-'0';

x=Pop(&S)-'0';

switch(ch){

case '+':Push(&S,(char)(x+y+'0'));break;

case '-':Push(&S,(char)(x-y+'0'));break;

case '*':Push(&S,(char)(x*y+'0'));break;

case '/':Push(&S,(char)(x/y+'0'));break;

}

}

}

return GetTop(S);

}

void main(){

SeqQueue Q; //定义队列,存放后缀表达式

InitQueue(&Q); //初始化队列

CTPostExp(&Q); //调用转换函数将中缀表达式转换成后缀表达式

printf("表达式的运算结果是:%c\n",CPostExp(Q)); //输出计算结果printf("表达式的后缀表达式为:");

while(!QueueEmpty(Q)) //输出后缀表达式

printf("%2c",DeQueue(&Q));

printf("\n");

}

相关主题
相关文档
最新文档