栈(Stack)
是一种限制存取点的线性表, 只能在一端进行插入或删除操作
栈顶和栈底
- 栈顶: 指栈中允许进行插入和删除操作的一端
- 栈底: 栈的另一端
栈的特性
典型的先入后出
栈的存储结构
- 顺序存储结构:
顺序栈
- 链式存储结构:
链栈
顺序栈
结构定义(相关宏定义参考线性表):
typedef struct { ElemType data[MAX_SIZE]; //顺序存储, 先进后出 int top; //存栈顶位置(只能在栈顶一端插入或删除) }SqStack;
操作集:
/* *初始化, 这里top存栈定元素的下一个位置, 同时也是栈的大小 */ void initStack(SqStack &sq){ sq.top = 0; } int size(SqStack &sq){ //栈大小 return sq.top; } int isEmpty(SqStack sq){ //判栈是否为空 return size(sq) == 0; } Status push(SqStack &sq, ElemType x){ //入栈 if(sq.top == MAX_SIZE) return ERROR; sq.data[sq.top++] = x; return OK; } Status pop(SqStack &sq, ElemType &x){ //出栈 if(isEmpty(sq)) return ERROR; x = sq.data[--sq.top]; return OK; } Status top(SqStack sq, ElemType &x){ //获取栈顶元素 if(isEmpty(sq)) return ERROR; x = sq.data[sq.top - 1]; return OK; }
特点:
- 有容量限制
- 插入删除简单
链栈
结构定义:
typedef struct LNode{ ElemType data; //数据域 struct LNode * next;//指针域 }LNode; /* * 一个头结点(不存储信息)指向表头 */
操作集:
/* *新建结点 */ LNode * newNode(ElemType x){ LNode * res = (LNode *)malloc(sizeof(LNode)); res->data = x; res->next = NULL; return res; } /* *插入操作, 这里栈顶第一个结点是表头的next指向的结点, 插入删除都在表头一端 *先入栈的元素在链表中后被删除(先进后出) *由于是链式结构, 所以一般没有容量限制, 插入操作都能够成功 */ void push(LNode * head, ElemType x){ LNode * tmp = newNode(x); tmp->next = head->next; //头插法 head->next = tmp; } int isEmpty(LNode * head){ //判空 return head->next == NULL; } Status pop(LNode * head, ElemType x){ if(isEmpty(head)) return ERROR; //栈为空 LNode * tmp = head->next; //当前栈顶 head->next = tmp->next; //修改栈顶 x = tmp->data; //返回元素值 free(tmp); return OK; } Status top(LNode * head, ElemType &x){ if(isEmpty(head)) return ERROR; x = head->next->data; return OK; }
特点
- 无容量限制
- 存储密度 < 1(指针域)
栈的应用
- 后缀表达式求值
- 函数调用时保护现场
- 递归过程
CodeUp 1743
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stack>
#define MAX_SIZE 100
#define Status int
#define OK 1
#define ERROR 0
#define ElemType Node
#define QElemType Node
/**
*Sequence Stack
**/
int prior[256];
void init(){
prior['+'] = prior['-'] = 0;
prior['*'] = prior['/'] = 1;
}
typedef struct{
int v;
int isOp;
}Node;
Node newNode(int _v, int _isOp){
Node res;
res.v = _v;
res.isOp = _isOp;
return res;
}
typedef struct{
QElemType data[MAX_SIZE];
int front;
int rear;
}SqQueue;
void initQueue(SqQueue &sq){
sq.front = sq.rear = 0;
}
Status Push(SqQueue &sq, QElemType x){
if((sq.rear + 1) % MAX_SIZE == sq.front) return ERROR;
sq.data[sq.rear++] = x;
return OK;
}
int IsEmpty(SqQueue sq){
return sq.front == sq.rear;
}
Status Pop(SqQueue &sq){
if(sq.front == sq.rear) return ERROR;
sq.front = (sq.front + 1) % MAX_SIZE;
return OK;
}
QElemType front(SqQueue sq){
return sq.data[sq.front];
}
typedef struct{
ElemType data[MAX_SIZE];
int top;
}SqStack;
void initStack(SqStack &sq){
sq.top = 0;
}
int size(SqStack sq){
return sq.top;
}
int isEmpty(SqStack sq){
return size(sq) == 0;
}
Status push(SqStack &sq, ElemType x){
if(sq.top == MAX_SIZE) return ERROR;
sq.data[sq.top++] = x;
return OK;
}
Status pop(SqStack &sq){
if(isEmpty(sq)) return ERROR;
--sq.top;
return OK;
}
ElemType top(SqStack sq){
return sq.data[sq.top - 1];
}
int isNum(char ch){
return ch >= '0' && ch <= '9';
}
void dealWithOperator(SqStack &sta, SqQueue &sq, char op){
if(op == '(' || op == ')'){
if(op == '(') push(sta, newNode(op, 1));
else{
while(top(sta).v != '('){
Push(sq, top(sta));
pop(sta);
}
pop(sta);
}
return;;
}
while(!isEmpty(sta) && top(sta).v != '(' && prior[op] <= prior[top(sta).v]){
Push(sq, top(sta));
pop(sta);
}
push(sta, newNode(op, 1));
}
double cal(double a, double b, int op){
if(op == '+') return a + b;
if(op == '-') return a - b;
if(op == '*') return a * b;
if(op == '/') return a / b;
}
int main(){
// freopen("in.txt", "r", stdin);
SqStack sta;
SqQueue sq;
init();
initQueue(sq);
initStack(sta);
char str[50];
char op = 0;
while(scanf("%s", str) != EOF){
int inNum = 0;
int num = 0;
for(int i = 0; str[i]; ++i){
if(isNum(str[i])){
if(inNum == 0) inNum = 1;
num = 10 * num + str[i] - '0';
}else{
if(inNum == 1){
Push(sq, newNode(num, 0));
num = 0;
inNum = 0;
}
if(str[i] != '#')dealWithOperator(sta, sq, str[i]);
}
}
while(!isEmpty(sta)){
ElemType cur = top(sta);
Push(sq, top(sta));
pop(sta);
}
std::stack<double> res;
while(!IsEmpty(sq)){
QElemType cur = front(sq);
if(cur.isOp == 1){
double op2 = res.top();
res.pop();
double op1 = res.top();
res.pop();
res.push(cal(op1, op2, cur.v));
}else res.push(cur.v);
Pop(sq);
}
printf("%.0f\n", res.top());
}
return 0;
}