# 堆栈的实现和逆波兰表达式的求值

21 篇文章 3 订阅

## 堆栈的实现：

堆栈分为顺序栈和链式栈两种，这里分别进行实现


### 顺序栈的实现：

typedef enum {true,false} bool;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode{
ElementType *Data;		/*存储元素的数组*/
Position Top;			/*栈顶指针*/
int MaxSize;			/*堆栈最大容量*/
};
typedef PtrToSNode Stack;


Stack CreateStack(int MaxSize){
Stack S = (Stack)malloc(sizeof(Stack));
S->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));
S->Top = -1;
S->MaxSize = MaxSize;
return S;
}


bool IsFull(Stack S){
return (S->Top == S->MaxSize - 1);
}
bool Push(Stack S,ElementType X){
if(IsFull(S)){
printf("堆栈满\n");
return false;
}else{
S->Data[++(S->Top)] = X;
return true;
}
}


bool IsEmpty(Stack S){
return (S->Top == -1);
}
ElementType Pop(Stack S){
if(IsEmpty(S)){
printf("堆栈空\n");
return ERROR;
}else{
return S->Data[(S->Top)--];
}
}


### 链式栈的实现：

这里实现的链式栈带有一个空的头节点


typedef enum {true,false} bool;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode{
ElementType Data;			/*存储的元素*/
PtrToSNode Next;			/*下一个元素*/
};
typedef PtrToSNode Stack;


Stack CreateStack(){
Stack S;
S = malloc(sizeof(sruct SNode));
S->Next = NULL;
return S;
}


bool Push(Stack S,ElementType X){
PtrToSNode TmpCell;
TmpCell = (PtrToSNode)malloc(sizeof(Struct SNode));
TmpCell->Data = X;
TmpCell->Next = S->Next;
S->Next = TmpCell;
return true;
}


bool IsEmpty(Stack S){
return (S->Next == NULL);
}
ElementType Pop(Stack S){
PtrToSNode FirstCell;
ElementType TopElem;
if(IsEmpty(S)){
printf("堆栈空\n");
return ERROR;
}
else {
FitstCell = S->Next;
TopElem = FirstCell->Data;
S->Next = FirstCell->Next;
free(FirstCell);
}
}


## 使用线性栈实现逆波兰表达式求值：

//这个程序是利用堆栈求后缀表达式的值
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>

#define MAXOP 100			/*操作数序列可能的最大长度*/
#define INFINITY 1e9 		/*代表正无穷*/
#define ERROR -INFINITY

typedef enum {num, opr, end} Type;
typedef enum {true,false} bool;

typedef double ElementType;
typedef int Position;
typedef struct SNode *PtrToSNode;
struct SNode{
ElementType *Data;		/*存储元素的数组*/
Position Top;			/*栈顶指针*/
int MaxSize;			/*堆栈最大容量*/
};
typedef PtrToSNode Stack;

Stack CreateStack(int MaxSize){
Stack S = (Stack)malloc(sizeof(Stack));
S->Data = (ElementType*)malloc(MaxSize*sizeof(ElementType));
S->Top = -1;
S->MaxSize = MaxSize;
return S;
}
bool IsFull(Stack S){
return (S->Top == S->MaxSize - 1);
}
bool Push(Stack S,ElementType X){
if(IsFull(S)){
printf("堆栈满\n");
return false;
}else{
S->Data[++(S->Top)] = X;
return true;
}
}
bool IsEmpty(Stack S){
return (S->Top == -1);
}
ElementType Pop(Stack S){
if(IsEmpty(S)){
printf("堆栈空\n");
return ERROR;
}else{
return S->Data[(S->Top)--];
}
}
Type GetOp(char * Expr, int * start,char * str){
/*从*start开始读下一个对象（操作数或者操作符），并保存在字符串str中*/

int i = 0;
/*跳过表达式前的空格*/
while((str[0] = Expr[(*start)++])==' ');

while(str[i]!=' ' && str[i] != '\0')
str[++i] = Expr[(*start)++];
if(str[i] == '\0')			/*如果读到输入的结尾*/
(*start)--;				/*start指向结束符*/
str[i] = '\0';				/*结束一个对象的获取*/

if(i == 0) return end;		/*读到了结束*/
/*如果str[0]是数字，或者是符号跟个数字*/
else if(isdigit(str[0]) || isdigit(str[1]))
return num;	/*表示str中存的仅仅是一个数字*/
else
return opr;	/*表示str中存的是一个表达式*/
}
ElementType PostfixExp(char* Expr){
Stack S;
Type T;
ElementType Op1,Op2;
char str[MAXOP];
int start = 0;

/*申请一个新的堆栈*/
S = CreateStack(MAXOP);

Op1 = Op2 = 0;
while((T = GetOp(Expr,&start,str))!=end){
/*当未读到结束时*/

if(T == num){
Push(S,atof(str));
} else {
if(!IsEmpty(S)) Op2 = Pop(S);
else Op2 = INFINITY;

if(!IsEmpty(S)) Op1 = Pop(S);
else Op2 = INFINITY;
switch(str[0]){
case'+':Push(S,Op1 + Op2);break;
case'*':Push(S,Op1 * Op2);break;
case'-':Push(S,Op1 - Op2);break;
case'/':
if(Op2 != 0.0)/*检查除法的分母是不是等于0*/
Push(S,Op1 / Op2);
else{
printf("错误：除法分母为0\n");
Op2 = INFINITY;
}
break;
default:
printf("错误：未知运算符：%s\n",str);
Op2 = INFINITY;
break;
}
if(Op2 == INFINITY) break;
}
}
if(Op2 <INFINITY)/*处理完了表达式*/
if(!IsEmpty(S))/*而此时堆栈正常*/
Op2 = Pop(S);
else Op2 = INFINITY;	/*否则标记错误*/
free(S); /*释放堆栈*/
return Op2;
}
int main(){
char Expr[MAXOP];
ElementType f;
gets(Expr);
f = PostfixExp(Expr);
if(f < INFINITY){
printf("%.f\n",f);
}else{
printf("表达式错误！！\n");
}
return 0;
}


• 程序的输入是一个逆波兰表达式，输出是这个表达式的值。
• 如果大家感兴趣的话，不妨点个赞，如果人多的话就更新中缀表达式转后缀表达式的代码。^ - ^
• 代码参考《数据结构（第2版）》----高等教育出版社
• 1
点赞
• 0
收藏
觉得还不错? 一键收藏
• 0
评论
08-16 179
11-18 1107
04-29
02-12 189
05-17 512
06-19 1122
09-05 208
02-04 1218
04-28 2437
01-11 818

### “相关推荐”对你有帮助么？

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

1.余额是钱包充值的虚拟货币，按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载，可以购买VIP、付费专栏及课程。