中缀表达式变为后缀表达式---数据结构栈的应用 C语言实现

数据结构学习之路之栈的应用——中缀表达式变为后缀表达式

最近在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");
}

总结:
表达式转换是对栈的运用的锻炼,能增加栈的理解,难点在于此题的逻辑分析,
若能仔细推敲,必会有所收获。

希望上述内容对您有所帮助。

以上部分内容参考
如有侵权,请联系作者,立刻删除。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值