数据结构学习之路之栈的应用——中缀表达式变为后缀表达式
最近在Mooc上观看浙江大学数据结构慕课,何钦铭教授讲了表达式转换的基本思路,
我按照自己的学习思路为大家阐述一下如何使用栈的一系列操作实现表达式的转换。
首先创建栈(我用的是顺序栈)
struct SNode {
int top;
char data[MaxSize];
};
typedef struct SNode *Stack;//指针,用于创建指向栈的指针
typedef struct SNode snode;//给struct SNode重命名
然后将栈的操作补上 (创建空栈,Pop(出栈) ,Push(入栈))
1.创建空栈
void InitStack(Stack S)
{
S->top = -1;
}
2.Push入栈
void Push(Stack S, int x)//入栈
{
if (S->top == MaxSize - 1)
printf("栈满");
else
{
S->top++;
S->data[S->top] = x;
}
}
3.Pop出栈
char Pop(Stack S)//出栈
{
if (S->top == -1)
{
printf("栈空");
return 0;
}
else return S->data[S->top--];
}
基本操作结束之后,整理思路,用一个例子开始:a+b*(c+d)
创建一个顺序栈;
创建两个字符数组str,str1;
str用来存放a+b*(c+d);
str1用来存放后缀表达式;
第一个字符为a,直接入str1;
第二个字符为+,此时栈空,直接入栈;
第三个字符为b,直接入str1;
第四个字符为*,此时与栈顶元素比较,优先级高于栈顶元素,入栈;
第五个字符为(,直接入栈,入栈后 ( 的优先级降到最低;
第六个字符为c,直接入str1;
第七个字符为+,此时与栈顶元素比较,优先级高于栈顶元素,入栈;
第八个字符为d,直接入str1;
第九个字符为),Pop出 ( 之前的所有元素;
最后若栈不为空,将栈内剩余元素全部输出到str1;
下附完整代码
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 20
#pragma warning(disable:4996)
struct SNode {
int top;
char data[MaxSize];
};
typedef struct SNode *Stack;
typedef struct SNode snode;
void InitStack(Stack S)
{
S->top = -1;
}
void Push(Stack S, int x)//入栈
{
if (S->top == MaxSize - 1)
printf("栈满");
else
{
S->top++;
S->data[S->top] = x;
}
}
char Pop(Stack S)//出栈
{
if (S->top == -1)
{
printf("栈空");
return 0;
}
else return S->data[S->top--];
}
void OutPutStack(Stack S)//用于输出栈内的元素(测试用)
{
int i = 0;
for (i = 0; i <= S->top; i++)
{
printf("S->data[S->top]=%c\n", S->data[S->top]);
}
}
int change(char op)//此函数用于判断输入字符优先级
{
int tag=-1;
if (op == '*' || op == '/')
tag = 2;
else if (op == '+' || op == '-')
tag = 1;
else if (op == '(')
tag = 0;
return tag;
}
int main()
{
char str[MaxSize] = { 0 };
char str1[MaxSize] = { 0 };
Stack S = (Stack)malloc(sizeof(snode));
InitStack(S);
int i = 0;
int j = 0;
printf("请输入前缀表达式:");
scanf_s("%c", &str[i],1);
while (str[i] != '\n')
{
int tag = change(str[i]);
if (str[i] >= '0'&&str[i] <= '9')//如果是数字直接入str1
{
str1[j] = str[i];
j++;
}
else
{
if (S->top == -1) //空直接入栈
{
Push(S, str[i]);
}
else if (str[i] == '(')//左括号直接入栈
{
Push(S, str[i]);
}
else if (str[i] == ')')
{
while (S->data[S->top] != '(')
{
str1[j] = Pop(S);
j++;
}
Pop(S);//将( Pop出去,不需要输出
}
else//若是运算符号,进行以下判断
{
while (change(str[i]) <= change(S -> data[S->top]))
{
str1[j] = Pop(S);
j++;
if (S->top == -1) break;
}
Push(S, str[i]);
}
}
//printf("str[%d]=%c\n", i, str[i]);
//OutPutStack(S);
i++;
scanf_s("%c", &str[i], 1);
}
while (S->top != -1)//若栈不空,则入str1
{
str1[j] = Pop(S);
j++;
}
printf("后缀表达式为:%s\n",&str1);
system("pause");
}
总结:
表达式转换是对栈的运用的锻炼,能增加栈的理解,难点在于此题的逻辑分析,
若能仔细推敲,必会有所收获。
希望上述内容对您有所帮助。