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

算法流程:

主要分为四步:

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/*

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

时间: 2024-10-27 13:06:04

数据结构之中序遍历转后续遍历(JAVA实现)(二)的相关文章

算法基础 - 通过前序遍历和中序遍历得到后续遍历

思想 思想很简单,前序遍历,第一个节点一定是当前树的根节点,而这个节点在中序遍历中,分割了左右子树. 假如前序: root left1 left2 left3 right1 right2 中序一定是: left left left root right right 虽然left在中序的顺序不能直接通过前序得到,但是一定知道的是,在中序遍历中,root分割了左右子树.然后递归得到左右子树的遍历,就可以得到整个树了. 代码如下: #include <iostream> #include <c

leetcode | 二叉树的前序遍历、中序遍历、后续遍历的非递归实现

Binary Tree Preorder Traversal:https://leetcode.com/problems/binary-tree-preorder-traversal/ Binary Tree Inorder Traversal :https://leetcode.com/problems/binary-tree-inorder-traversal/ Binary Tree Postorder Traversal:https://leetcode.com/problems/bin

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

算法流程: 主要分为四步: 1.当前字符为数字或者字母,则直接输出 2.当前字符为).则在栈中匹配输出.一直匹配到),则停止输出(就是将)及其顶上的元素所有弹出来输出) 3.当前字符为操作符.则比較当前字符的入栈优先级(icp)和字符栈内优先级(isp).假设icp<=isp,则将栈内操作符弹出输出,然后反复3 4.当前字符为空,则将栈中元素依次弹出输出 百度百科上面的描写叙述: 1.建立运算符栈stackOperator用于运算符的存储.压入'\0'. 2.预处理表达式,正.负号前加0(假设一

数据结构 二叉树 已知前序中序遍历求后续遍历的递归实现

代码很短,实现起来也很简单,下面是代码: // // main.cpp // PreMidgetPost // // Created by xin wang on 4/29/15. // Copyright (c) 2015 xin wang. All rights reserved. // #include <iostream> //链表二叉树的节点类 template <class T> class BinaryTreeNode{ public: BinaryTreeNode(

【LeetCode】106. Construct Binary Tree from Inorder and Postorder Traversal-通过中序和后续遍历还原二叉树

一.描述: 二.思路: 二叉树的中序遍历和前序遍历或和后续遍历能唯一确定一节课二叉树,即2中还原方式都需要中序遍历才能完成: 设二叉树的前序遍历序列为{1, 2, 4, 5, 3, 6},中序遍历序列为{4,2,5,1, 3, 6}:(红色标记表示以还原节点!!!) (1)-前序遍历的第一个节点是二叉树的根节点,{1, 2, 4, 5, 3, 6},对应中序中的位置是{4,2,5,1, 3, 6},所以中序序列中的 '1' 之前的全部元素为左子树元素,'1'之后的为右子树元素: (2)-左子树对

后续遍历 java leecode

以前觉得后续遍历最难写,今天看了篇博客http://blog.csdn.net/sgbfblog/article/details/7773103,其实却是我们仔细比较后续遍历和先序遍历,其实后续遍历就是按照  根右左 的方式先序访问然后逆序就是答案了,会先序就会逆序了 leecode 的AC代码: public class Solution { public List<Integer> postorderTraversal(TreeNode root) { ArrayList<Integ

树的前中序遍历_求后续遍历

原文链接:http://blog.csdn.net/feliciafay/article/details/6816871 PreOrder:         GDAFEMHZ InOrder:           ADEFGHMZ PostOrder:       AEFDHZMG 现在,假设仅仅知道前序和中序遍历,如何求后序遍历呢?比如,已知一棵树的前序遍历是”GDAFEMHZ”,而中序遍历是”ADEFGHMZ”应该如何求后续遍历? 第一步,root最简单,前序遍历的第一节点G就是root.

数据结构之 二叉树---求二叉树后序遍历和层次遍历(先建树,再遍历)

数据结构实验之求二叉树后序遍历和层次遍历 Time Limit: 1000MS Memory limit: 65536K 题目描述 已知一棵二叉树的前序遍历和中序遍历,求二叉树的后序遍历. 输入 输入数据有多组,第一行是一个整数t (t<1000),代表有t组测试数据.每组包括两个长度小于50 的字符串,第一个字符串表示二叉树的先序遍历序列,第二个字符串表示二叉树的中序遍历序列. 输出 每组第一行输出二叉树的后序遍历序列,第二行输出二叉树的层次遍历序列 示例输入 2 abdegcf dbgeaf

已知二叉树的先序,中序遍历,求后续遍历

//已知二叉树的先序,中序遍历,求后续遍历 struct TreeNode { char elem; struct TreeNode* left; struct TreeNode* right; }; TreeNode* BinaryTree(char* inorder,char* preorder,int length) { if(length == 0) return NULL; TreeNode* node = new TreeNode; node->elem = *preorder; i