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

堆栈的实现:

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

顺序栈的实现:

栈结构的定义:

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);
		return TopElem;
	}
}

值得注意的是,在使用链式栈的时候,栈的大小并不需要固定,因为只要电脑有可用的内存,那么这条链就可以一直延伸。

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

//这个程序是利用堆栈求后缀表达式的值
#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
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值