中缀表达式就是我们习惯的表达式比如说1+2*3,后缀表达式是计算机习惯的表达式。
1+2*3转成后缀表达式后:123*+
中缀转后缀算法:
- 遍历中缀表达式中的数字和符号:
- 对于符号:
- 左括号:进栈
- 若栈顶符号优先级低:此符号进栈(默认栈顶若是左括号,左括号优先级最低)
若栈顶符号优先级不低:将栈顶符号弹出并输出,之后进栈
右括号:将栈顶符号弹出并输出,直到匹配左括号遍历结束:将栈中的所有符号弹出并输出
数字直接输出:———————————结果:8
运算符要先判断优先级,但现在栈为空直接将它进行压栈
直接将左括号压栈
数字直接输出———————-结果:83
碰到运算符将他与当前栈顶比较,括号优先级最低所以-进栈
输出—————结果:831
碰到右括号将栈顶符号弹出并输出,直到匹配左括号 结果:831-
(括号会抵消掉)
乘号优先级比加高,*进栈
输出——————–结果:831-5
此时以指向 \0 结束符将栈里的元素逐个弹出,结果:831-5*+
.h
//链式栈的节点
typedef struct LINKNODE
{
struct LINKNODE*next;
}LinkNode;
//链式栈
typedef struct LINKSTACK
{
LinkNode head;
int size;
}LinkStack;
class linkstack
{
public:
linkstack();
~linkstack();
public:
LinkStack* Stack;
public:
//入栈
void push_back(LinkStack* stack,LinkNode* data);
//出栈
void pop_back(LinkStack* stack);
//返回栈顶元素
LinkNode* Top_LinkStack(LinkStack* stack);
//返回栈元素的个数
int Size_LinkStack(LinkStack* stack);
//清空栈
void Clear_LinkStack(LinkStack* stack);
};
.cpp
linkstack::linkstack()
{
Stack = new LinkStack;
Stack->head.next = NULL;
Stack->size = 0;
}
linkstack::~linkstack()
{
if (Stack == NULL)
{
return;
}
delete Stack;
}
//入栈
void linkstack::push_back(LinkStack* stack, LinkNode* data)
{
if (stack == NULL || data == NULL)
{
return;
}
data->next = stack->head.next;
stack->head.next = data;
stack->size++;
}
//出栈
void linkstack::pop_back(LinkStack* stack)
{
if (stack == NULL || stack->size == 0)
{
return;
}
LinkNode* pNext = stack->head.next;
stack->head.next = pNext->next;
stack->size--;
}
//返回栈顶元素
LinkNode* linkstack::Top_LinkStack(LinkStack* stack)
{
if (stack == NULL || stack->size == 0)
{
return NULL;
}
return stack->head.next;
}
//返回栈元素的个数
int linkstack::Size_LinkStack(LinkStack* stack)
{
if (stack == NULL )
{
return -1;
}
return stack->size;
}
//清空栈
void linkstack::Clear_LinkStack(LinkStack* stack)
{
if (stack == NULL || stack->size == 0)
{
return;
}
stack->head.next = NULL;
stack->size = 0;
}
main.cpp
linkstack* s = new linkstack();
//判断是否是数字
int IsNumber(char c)
{
return c >= '0' && c <= '9';
}
//判断是否为左括号
int IsLeft(char c)
{
return c == '(';
}
//判断是否为右括号
int IsRight(char c)
{
return c == ')';
}
//判断是否为运算符
int IsOperator(char c)
{
return c == '+' || c == '-' || c == '*' || c == '/';
}
//返回运算符优先级
int GetPriority(char c)
{
if (c == '*' || c == '/')
{
return 2;
}
if (c == '+' || c == '-')
{
return 1;
}
return 0;
}
typedef struct MYCHAR
{
LinkNode node;
char* p;
}MyChar;
//数字操作
void NuberOperate(char* p)
{
cout << *p;
}
//创建MyChar
MyChar* CreateMyChar(char* p)
{
MyChar* mychar = new MyChar;
mychar->p = p;
return mychar;
}
//左括号操作
void LeftOperate(LinkStack* stack,char* p)
{
s->push_back(stack,(LinkNode*)CreateMyChar(p));
}
//右括号操作
void RinghtOperate(LinkStack* stack)
{
//判断栈中有没有元素
while (s->Size_LinkStack(s->Stack) >0)
{
MyChar* mychar = (MyChar*)s->Top_LinkStack(s->Stack);
//如果匹配到左括号
if (IsLeft(*mychar->p))
{
s->pop_back(s->Stack);
break;
}
//输出
cout << *mychar->p;
//弹出
s->pop_back(stack);
//释放内存
delete mychar;
}
}
//运算符操作
void OperatorOperator(LinkStack* stack,char* p)
{
//先取出栈顶元素
MyChar* mychar = (MyChar*)s->Top_LinkStack(stack);
if (mychar == NULL)
{
s->push_back(stack, (LinkNode*)CreateMyChar(p));
return;
}
//如果栈顶优先级低于当前字符优先级 直接入栈
if (GetPriority(*mychar->p) < GetPriority(*p))
{
s->push_back(stack,(LinkNode*)CreateMyChar(p));
return;
}
else //如果栈顶优先级不低
{
while (s->Size_LinkStack(stack) >0)
{
MyChar* mychar2 = (MyChar*)s->Top_LinkStack(stack);
//如果优先级低 当前符号入栈
if (GetPriority(*mychar2->p) < GetPriority(*p))
{
s->push_back(stack,(LinkNode*)CreateMyChar(p));
break;
}
//输出
cout <<*mychar2->p;
//弹出
s->pop_back(stack);
//释放内存
delete mychar2;
}
}
}
int main()
{
char* str = "8+(3-1)*5";
char* p = str;
while (*p != '\0')
{
//如果是数字直接输出
if (IsNumber(*p))
{
NuberOperate(p);
goto go;
}
//如果是左括号直接进栈
if (IsLeft(*p))
{
LeftOperate(s->Stack, p);
goto go;
}
//如果是右括号
if (IsRight(*p))
{
RinghtOperate(s->Stack);
goto go;
}
//如果是运算符
if (IsOperator(*p))
{
OperatorOperator(s->Stack,p);
goto go;
}
go:
p++;
}
while (s->Size_LinkStack(s->Stack) >0)
{
MyChar* mychar = (MyChar*)s->Top_LinkStack(s->Stack);
cout << *mychar->p;
s->pop_back(s->Stack);
delete mychar;
}
delete s;
return 0;
}
结果: