栈和队列一()
1、类型
- 最大栈
- 最小栈
- 流式数据的最小值
- 单调队列
- 两个栈实现一个队列
- 栈的前缀后缀表达式求值
- 栈的出栈序列判断
- 其他
2、基本应用
1) 150. 逆波兰表达式求值 后缀表达式求值
波兰表达式计算 > 输入: ["2", "1", "+", "3", "*"] > 输出: 9
解释: ((2 + 1) * 3) = 9
学栈的时候,我们需要两个栈,一个是符号栈,一个是操作数栈,()需要去除。
import java.util.Stack;
class Solution {
public int evalRPN(String[] tokens) {
Stack<Integer> s = new Stack<>();
for(String s1:tokens){
if(s1.equals("+")||s1.equals("-")||s1.equals("/")||s1.equals("*")){
int a = s.pop();
int b = s.pop();
if(s1.equals("+")){
s.push(b+a);
}else if(s1.equals("-")){
s.push(b-a);
}else if(s1.equals("*")){
s.push(b*a);
}else{
s.push(b/a);
}
}
else
s.push(Integer.parseInt(s1));
}
return s.pop();
}
}
做完这道题,我们先来回顾以下相关知识点。(图解),这里代码实现了如下内容:
3、实现前序、后序、中序表达式的互相转化及构建二叉树(代码实现)
方法讲解参考:
https://blog.csdn.net/walkerkalr/article/details/22798365
package Stack;
import javax.swing.plaf.synth.SynthOptionPaneUI;
import java.util.Stack;
public class HouZhui_QianZui_MidZhui {
public static void main(String[] args) {
String[] mid = {"1","+", "(","(","2","/", "3",")","*","4",
")", "-" ,"5","*","6","-","9","*","10","-","6"};
System.out.println("中缀表达式");
printStringArray(mid);
String[] strings = MidZhuiToHouZhui(mid);
System.out.println("后缀表达式");
printStringArray(strings);
double v = CountHouZhui(strings);
System.out.println(v);
String[] strings1 = MidZuiToQianZhui(mid);
System.out.println("前缀表达式");
printStringArray(strings1);
double v1 = CountQianZhui(strings1);
System.out.println(v1);
System.out.println(CountMidZhui(mid));
System.out.println("==================后缀转中缀====================");
System.out.println("后缀逆序为中缀");
printStringArray(strings);
String[] strings2 = HouZhuiToMid(strings);
printStringArray(strings2);
System.out.println("格式化完毕");
System.out.println("计算后缀:");
String[] strings3 = MidZhuiToHouZhui(strings2);
System.out.println("转化的后缀表达式:");
printStringArray(strings3);
System.out.println("计算前缀");
String[] strings4 = MidZuiToQianZhui(strings2);
System.out.println("转化的前缀表达式:");
printStringArray(strings4);
System.out.println("计算每一种表达式的值");
System.out.println(CountQianZhui(strings4));
System.out.println(CountHouZhui(strings3));
System.out.println(CountMidZhui(strings2));
System.out.println("======后缀表达式构造二叉树=======");
TreeNode treeNode = constructTreeByMinZhui(strings);
treeNode.traver(0);
treeNode.traver(1);
treeNode.traver(2);
}
public static void printStringArray(String[] token){
if(token==null || token.length==0){
System.out.print("null");
return;
}
for(String s:token){
System.out.print(s);
}
System.out.println();
}
public static int priority(String operator){
if(operator==null || operator.length()>=2){
return -1;
}
int priority = -1;
switch (operator){
case "*":
case "/":priority = 2;break;
case "+":
case "-":priority = 1;break;
case "(":
case ")":priority = 0;break;
default: break;
}
return priority;
}
public static String[] HouZhuiToMid(String[] tokens){
System.out.println("后缀转中缀表达式");
Stack<String> stack = new Stack<>();
for(String s:tokens){
if("".equals(s)||s==null){
continue;
}
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("(")||s.equals(")")){
String a1 = stack.pop();
String a2 = stack.pop();
switch (s){
case "+":stack.push("(="+a2+"=+="+a1+"=)=");break;
case "/":stack.push(a2+"=/="+a1+"=");break;
case "*":stack.push(a2+"=*="+a1+"=");break;
case "-":stack.push("(="+a2+"=-="+a1+"=)=");break;
}
}else {
stack.push(s+"=");
}
}
StringBuilder s = new StringBuilder();
while(!stack.isEmpty()){
s.append(stack.pop());
}
String[] split = s.toString().split("=");
StringBuilder s2 = new StringBuilder();
int i=0;
for(String temp :split){
if(!"".equals(temp)){
s2.append(temp);
s2.append("=");
}
}
return s2.toString().split("=");
}
public static String[] MidZuiToQianZhui(String[] tokens){
StringBuilder hou_tokens = new StringBuilder();
Stack<String> stack = new Stack<>();
for(int i=tokens.length-1;i>=0;i--){
String s = tokens[i];
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("(")||s.equals(")")){
if(stack.isEmpty()){
stack.push(s);
}else{
if(s.equals(")")){
stack.push(s);
continue;
}
String peek = stack.peek();
int peek1 = priority(peek);
int s1 = priority(s);
if(s1>=peek1){
stack.push(s);
}else{
if(s.equals("(")){
while(!stack.peek().equals(")")){
hou_tokens.append(stack.pop());
hou_tokens.append("=");
}
stack.pop();
}else{
while(!stack.isEmpty() && priority(stack.peek())>s1){
hou_tokens.append(stack.pop());
hou_tokens.append("=");
}
stack.push(s);
}
}
}
}else {
hou_tokens.append(s);
hou_tokens.append("=");
}
}
while (!stack.isEmpty()){
hou_tokens.append(stack.pop());
hou_tokens.append("=");
}
String[] split = hou_tokens.toString().split("=");
String[] s = new String[split.length];
int c=0;
for(int i=split.length-1;i>=0;i--){
s[c++] = split[i];
}
return s;
}
public static String[] MidZhuiToHouZhui(String[] tokens){
StringBuilder hou_tokens = new StringBuilder();
Stack<String> stack = new Stack<>();
for(String s:tokens){
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("(")||s.equals(")")){
if(stack.isEmpty()){
stack.push(s);
}else{
if(s.equals("(")){
stack.push(s);
continue;
}
String peek = stack.peek();
int peek1 = priority(peek);
int s1 = priority(s);
if(s1>peek1){
stack.push(s);
}else{
if(s.equals(")")){
while(!stack.peek().equals("(")){
hou_tokens.append(stack.pop());
hou_tokens.append("=");
}
stack.pop();
}else{
while(!stack.isEmpty() && priority(stack.peek())>=s1){
hou_tokens.append(stack.pop());
hou_tokens.append("=");
}
stack.push(s);
}
}
}
}else {
hou_tokens.append(s);
hou_tokens.append("=");
}
}
while (!stack.isEmpty()){
hou_tokens.append(stack.pop());
hou_tokens.append("=");
}
return hou_tokens.toString().split("=");
}
public static double CountHouZhui(String[] tokens){
Stack<Double> stack = new Stack<>();
System.out.println("计算后缀表达式");
printStringArray(tokens);
for(String s:tokens){
if("".equals(s)||s==null){
continue;
}
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("(")||s.equals(")")){
double a1 = stack.pop();
double a2 = stack.pop();
switch (s){
case "+":stack.push(a2+a1);break;
case "/":stack.push(a2/a1);break;
case "*":stack.push(a2*a1);break;
case "-":stack.push(a2-a1);break;
}
}else {
stack.push((double) Integer.parseInt(s));
}
}
return stack.pop();
}
public static double CountQianZhui(String[] tokens){
Stack<Double> stack = new Stack<>();
System.out.println("计算前缀表达式");
printStringArray(tokens);
for(int i=tokens.length-1;i>=0;i--){
String s = tokens[i];
if("".equals(s)||s==null){
continue;
}
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("(")||s.equals(")")){
double a2 = stack.pop();
double a1 = stack.pop();
switch (s){
case "+":stack.push(a2+a1);break;
case "/":stack.push(a2/a1);break;
case "*":stack.push(a2*a1);break;
case "-":stack.push(a2-a1);break;
}
}else {
stack.push((double) Integer.parseInt(s));
}
}
return stack.pop();
}
public static double CountMidZhui(String[] tokens){
System.out.println("计算中缀表达式 转化后缀表达式再计算");
printStringArray(tokens);
String[] strings = MidZhuiToHouZhui(tokens);
return CountHouZhui(strings);
}
public static TreeNode constructTreeByMinZhui(String[] tokens){
if(tokens==null||tokens.length==0){
return null;
}
System.out.println("构建树");
printStringArray(tokens);
Stack<TreeNode> stack = new Stack<>();
for(String s:tokens){
if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")||s.equals("(")||s.equals(")")){
if(s.equals("(") ||s.equals(")")){
continue;
}
TreeNode treeNode = new TreeNode(s);
treeNode.right = stack.pop();
treeNode.left = stack.pop();
stack.push(treeNode);
}else {
stack.push(new TreeNode(s));
}
}
return stack.pop();
}
static class TreeNode {
String val;
TreeNode left;
TreeNode right;
public TreeNode(String val) {
this.val = val;
}
public TreeNode(String val, TreeNode left, TreeNode right) {
this.val = val;
this.left = left;
this.right = right;
}
public void traver(int i){
if(i==0){
System.out.println("前序遍历");
preTraver(this);
System.out.println();
}
else if(i==1){
System.out.println("中序遍历");
midTraver(this);
System.out.println();
}else if(i==2){
System.out.println("后续遍历");
postTraver(this);
System.out.println();
}else {
throw new RuntimeException("不支持的参数!");
}
}
private void postTraver(TreeNode root) {
if(root==null){
return;
}
postTraver(root.left);
postTraver(root.right);
System.out.print(root.val+" ");
}
private void midTraver(TreeNode root) {
if(root==null){
return;
}
midTraver(root.left);
System.out.print(root.val+" ");
midTraver(root.right);
}
private void preTraver(TreeNode root) {
if(root==null){
return;
}
System.out.print(root.val+" ");
preTraver(root.left);
preTraver(root.right);
}
}
}
例子演示:
构建树:这里只实现了后序表达式构建树:
代码可能有错误,因为没有经过大量用例测试
|