栈&中缀转后缀
栈
概念
栈,同样是一种特殊的线性表,是一种Last In First Out(LIFO)的形式,现实中有很多这样的例子,
比如:食堂中的一叠盘子,我们只能从顶端一个一个的取。
栈是一种特殊的线性表,仅能在线性表的一端操作,栈顶允许操作,栈底不允许操作。
栈的特性:先进后出 后进先出
栈的基本操作包括创建栈、销毁栈、出栈、入栈、获取栈顶元素、获取栈的大小、清空栈。
stack.h
#pragma once
typedef int ElemType;
#define STACKSIZE 10
typedef struct _Stack
{
ElemType *data;
int top;
}SqStack, *pSqStack;
bool InitStack(pSqStack st);
bool IsEmpty(pSqStack st);
void DestroyStack(pSqStack st);
void ClearStack(pSqStack st);
bool GetTop(pSqStack st, ElemType *val);
bool Push(pSqStack st, ElemType val); // 入栈
bool Pop(pSqStack st); // 出栈
//////////////////////////////////
/*
template <Type>
class Stack
{
public:
Stack()
{
}
~Stack()
{
}
bool Push(Type val)
{
}
bool Pop()
{
}
bool GetTop(Type &val)
{
}
private:
bool IsEmpty(){}
bool IsFull(){}
private:
Type *data;
int top;
};
*/
stack.cpp
#include "stack.h"
#include <assert.h>
#include <stdio.h>
#include <malloc.h>
///////////////////////////
bool IsEmpty(pSqStack st)
{
return st->top == 0;
}
static bool IsFull(pSqStack st)
{
return st->top == STACKSIZE;
}
///////////////////////////
bool InitStack(pSqStack st)
{
assert(st != NULL);
if (st == NULL) return false;
st->data = (ElemType*)malloc(sizeof(ElemType)* STACKSIZE);
assert(st->data != NULL);
if (st->data == NULL) return false;
st->top = 0;
return true;
}
void DestroyStack(pSqStack st)
{
free(st->data);
st->data = NULL;
st->top = 0;
}
void ClearStack(pSqStack st)
{
st->top = 0;
}
bool GetTop(pSqStack st, ElemType *val)
{
if (IsEmpty(st)) return false;
*val = st->data[st->top - 1];
return true;
}
bool Push(pSqStack st, ElemType val) // 入栈
{
if (IsFull(st)) return false;
st->data[st->top++] = val;
return true;
}
bool Pop(pSqStack st) // 出栈
{
if (IsEmpty(st)) return false;
st->top--;
return true;
}
利用栈完成中缀转后缀的主函数
中缀表达式转后缀表达式:
1.遇到数字直接输出
2.遇到左括号"("直接入栈
3.遇到 * 或者 /,开始出栈,直到栈为空或者遇到“(”或者遇到 + -符号
4.如果遇到+或者-,开始出栈,直到栈空。或者遇到左括号就不出栈了,将当前符号入栈。
5.如果遇到右括号,开始出栈直到遇到左括号。
6.如果字符串访问完,再将栈出空。
const char *str = "9+(3-1)*3+10/2";
//9 3 1 -3*+10 2/+
// const char *str2 = "9*3/2*6";
//9 3 *2 /6
比较方便的版本:
中缀转后缀C++代码实现(比较方便)
1.遇到操作数:添加到后缀表达式中或直接输出
2.栈空时:遇到运算符,直接入栈
3.遇到左括号:将其入栈
4.遇到右括号:执行出栈操作,输出到后缀表达式,直到弹出的是左括号
注意:左括号不输出到后缀表达式
5.遇到其他运算符:弹出所有优先级大于或等于该运算符的栈顶元素,然后将该运算符入栈
6.将栈中剩余内容依次弹出后缀表达式
#include "stack.h"
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
SqStack st;
InitStack(&st);
char *str = "9+(3-1)*3+10/2";
int i = 0;
while (str[i] != 0)
{
while (true) // 遇到数字直接输出
{
if (isdigit(str[i]))
printf("%c", str[i++]);
else
{
printf(" ");
break;
}
}
if (str[i] == '(') // 遇到左括号直接入栈
{
Push(&st, str[i]);
}
else if (str[i] == '*' || str[i] == '/') // 遇到*或/,开始出栈,直到遇到左括号或者+-或者栈空
{
while (true)
{
int val = 0;
if (!GetTop(&st, &val) || val == '+' || val == '-' || val == '(')
{
break;
}
Pop(&st);
printf("%c ", val);
}
Push(&st, str[i]);
}
else if (str[i] == ')') //遇到右括号,出栈,直到遇到左括号
{
int val = 0;
while (true)
{
GetTop(&st, &val);
Pop(&st);
if (val == '(')
{
break;
}
printf("%c ", val);
}
}
else //遇到+或者- 直接出栈 直到栈空或者遇到左括号
{
while (true)
{
int val = 0;
if (!GetTop(&st, &val) || val == '(')
{
break;
}
printf("%c ", val);
Pop(&st);
}
Push(&st, str[i]);
}
i++;
}
while (!IsEmpty(&st)) // 将栈中剩余的符号输出
{
int val = 0;
GetTop(&st, &val);
printf("%c ", val);
Pop(&st);
}
printf("\n");
}