一、栈
参考书:《数据结构(C语言)》–严蔚敏等编著,清华大学出版社。
1、顺序栈的后缀表达式求值操作
栈和队列同线性表一样,也是线性结构,它们是线性表的子集(是插入和删除受限的线性表),如本节栈非常重要的一大特点是:后进先出(先进后出)LIFO结构。
栈的顺序存储结构是利用一组连续的存储单元依次存放自栈底到栈顶的数据元素,同时附带指针top指向栈顶元素,为了方便计算,通常非空栈中的栈顶指针top始终指向栈顶元素的下一个位置。
而:
top=0 或者 S.base == S.top都表示空栈
base==NULL表示栈结构不存在
S.top - S.base = stacksize 表示满栈
栈的顺序存储表示的优点是简单,方便,但缺点是容易产生溢出(原因是栈的存储是固定的,top达到一定高度就满了);
如图是进栈出栈简单操作:
相关代码:
#include "stdio.h"
#include "stdlib.h"
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
typedef int Status;
typedef int SElemType;
typedef struct{
SElemType *base;
SElemType *top;
int stacksize; //当前已分配的存储空间
}SqStack;
Status InitStack_Sq(SqStack &S);
//构造一个空栈S,栈top初始化
Status InitStack_Sq(SqStack &S){
S.base=(SElemType *)malloc(STACK_INIT_SIZE*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top = S.base; //表示为空栈
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status Push_Sq(SqStack &S,SElemType e);
//进栈
Status Push_Sq(SqStack &S,SElemType e){
if(S.top - S.base >= S.stacksize){
S.base=(SElemType *)realloc(S.base,
(S.stacksize+STACKINCREMENT)*sizeof(SElemType));
if(!S.base) exit(OVERFLOW);
S.top = S.base + S.stacksize;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e; //先将新元素赋给top位置,后将top上移 *S.top=e;S.top++;
return OK;
}
Status Pop_Sq(SqStack &S,SElemType &e);
//出栈
Status Pop_Sq(SqStack &S,SElemType &e){
if(S.top==S.base) return ERROR;
e = * --S.top; //或--S.top; e=*S.top;
return OK;
}
Status Operator_Sq(int e1,char ch,int e2);
//后缀表达式操作
Status Operator_Sq(int e1,char ch,int e2){
switch(ch){
case '+': return e1+e2; break;
case '-': return e1-e2; break;
case '*': return e1*e2; break;
case '/': return e1/e2; break;
}
}
int main(void){
SqStack S;
InitStack_Sq(S);
char ch;int c,e1,e2,result;
scanf("%c",&ch);
while(ch != '#'){
if(ch=='+' || ch=='-' || ch=='*' || ch=='/'){
Pop_Sq(S,e2);
Pop_Sq(S,e1);
result=Operator_Sq(e1,ch,e2);
Push_Sq(S,result);
}
else{
c=ch-'0'; //遇到数值 进栈
Push_Sq(S,c);
}
scanf("%c",&ch);
}
Pop_Sq(S,result);
printf("%d",result);
return 0;
}
/*
输入:931–3*+82/+#(#代表输入结束)
输出:19
输入:2278---#(注意这里是三个-号)
输出:-1
*/