数据结构之中序遍历转后续遍历(JAVA实现)(二)

28 篇文章 2 订阅

   算法流程:

   主要分为四步:

        1.当前字符为数字或者字母,则直接输出

        2.当前字符为),则在栈中匹配输出,一直匹配到),则停止输出(就是将)及其顶上的元素全部弹出来输出)

        3.当前字符为操作符,则比较当前字符的入栈优先级(icp)和字符栈内优先级(isp),如果icp<=isp,则将栈内操作符弹出输出,然后重复3

       4.当前字符为空,则将栈中元素依次弹出输出

  百度百科上面的描述:

        1、建立运算符栈stackOperator用于运算符的存储,压入'\0'。
        2、预处理表达式,正、负号前加0(如果一个加号(减号)出现在最前面或左括号后面,则该加号(减号)为正负号) 。
       3、顺序扫描表达式,如果当前字符是数字(优先级为0的符号),则直接输出该数字;如果当前字符为运算符或括号(优先级不为0的符号),则判断第4点 。
       4、若当前运算符为'(',直接入栈;若为')',出栈并顺序输出运算符直到遇到第一个'(',遇到的第一个'('出栈但不输出;若为四则运算符,比较栈顶元素与当前元素的优先级:如果 栈顶元素运算符优先级 >= 当前元素的优先级,出栈并顺序输出运算符直到 栈顶元素优先级 < 当前元素优先级,然后当前元素入栈;如果 栈顶元素 < 当前元素,直接入栈。
       5、重复第3点直到表达式扫描完毕。
       6、顺序出栈并输出运算符直到栈顶元素为'\0'。  


   当然我自己理解的就是按照自己实现的简单变化,没有包括大括号

   我的代码:

   

	// 中序遍历改为后续遍历
		public String tranform(String obj)
			{
				Stack<Character> stack = new Stack<Character>();
				String obj2 = "";
				for (int i = 0; i < obj.length(); i++)
					{
						char ch = obj.charAt(i);
						if (Character.isLetter(ch))// 字母或数字直接输出
							{
								obj2 += ch;
								System.out.println(ch);
							} else if (ch == ')')// 在栈中一致匹配到)操作符才停止出栈
							{
								char temp;
								while ((temp = stack.pop()) != '(')
									{
										obj2 += temp;
										System.out.println(temp);
									}
							} else
							// 比较操作符的进栈优先级
							{
								if(stack.isEmpty())
									{
										stack.push(ch);
										continue;
									}
								char temp = stack.peek();
								while (icp(ch) <= isp(temp))//进栈优先级小于栈内优先级,则一直出栈
									{
										System.out.println(temp);
										obj2+=temp;
                                                                                stack.pop();
                                                                                if(stack.isEmpty())break;
                                                                                temp=stack.peek();                                      
									}
								stack.push(ch);
							}
					}
				//将栈中剩余的元素弹出来
				while(!stack.isEmpty())
					{
						char temp=stack.pop();
						obj2+=temp;
						System.out.println(temp);
					}
				return obj2;
			}

		// 操作符在栈内的优先级
		private int isp(char ch)
			{
				switch (ch)
					{
					case '+':
					case '-':
						return 2;
					case '*':
					case '/':
						return 4;
					case ')':
						return 7;
					case '(':
						return 1;
					default:
						break;
					}
				return 0;
			}

		// 操作符进栈的优先级优先级
		private static int icp(char ch)
			{
				switch (ch)
					{
					case '+':
					case '-':
						return 3;
					case '*':
					case '/':
						return 5;
					case ')':
						return 1;
					case '(':
						return 7;
					default:
						break;
					}
				return 0;
			}

		public static void main(String[] args)
			{
				String objString="a*(b+c)+c/d";
				TreeNode<Character> treeNode=new TreeNode<Character>(null);
				treeNode.tranform(objString);

			}
   运行效果:

     

a*(b+c)+c/d   -》 abc+*cd/*

如果利用这个后序遍历很容易实现一个简单的计算器,除此之外,我记得一个基于文法的计算器,等下一次实现。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值