赞
踩
栈是一种特殊的线性表,只能在一段进行插入和删除操作,遵循先进后出原则。
所以当栈的存储方式为链式并且是单链表时, 入栈选头插法是最好的选择。
栈继承了Vector,Vector和ArrayList类似,属于动态顺序表,Vector属于线程安全。
//创建一个栈
public class Stack {
public int[] elem;
public int usedSize;
public static final int DEFAULT_CAPATI = 5;
public Stack(){
elem = new int[DEFAULT_CAPATI];
}
}
//入栈push() //判满 public boolean isFull(){ if (usedSize == elem.length){ return true; } return false; } public void push(int val){ if (isFull()){ //扩容 elem = Arrays.copyOf(elem,2*elem.length); } elem[usedSize] = val; usedSize++; }
//出栈pop() //判空 public boolean isEmpty(){ return usedSize == 0; } //如果栈是空 抛出一个异常 EmptyStackException public class EmptyStackException extends RuntimeException{ public EmptyStackException(){ } public EmptyStackException(String msg){ super(msg); } } public int pop(){ if (isEmpty()){ throw new EmptyStackException("栈是空栈"); } int oldVal = elem[usedSize-1]; usedSize--; return oldVal; }
//获取栈顶元素 peek()
public int peek(){
if (isEmpty()){
throw new EmptyStackException("栈是空栈");
}
return elem[usedSize-1];
}
//获取有效元素个数
public int getUsedSize(){
return usedSize;
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>();
stack.push(1);
stack.push(2);
stack.push(3);
stack.push(4);
stack.pop();
System.out.println(stack.getUsedSize());
System.out.println(stack.peek());
}
括号匹配
思路:我们考虑使用栈,当遇到匹配的最小括号对时,我们将这对括号从栈中删除(即出栈),如果最后栈为空,那么它是有效的括号,反之不是。
代码展示:
class Solution { public boolean isValid(String s) { Stack<Character> stack = new Stack<>(); for(int i=0;i<s.length();i++){ char ch=s.charAt(i); if(ch=='{' || ch=='('||ch=='['){ stack.push(ch); }else{ //说明是右括号 if(stack.empty()){ //右括号多 return false; } char top =stack.peek(); if(ch==')' && top=='(' || ch==']' && top=='[' || ch=='}' && top=='{' ){ //只能说明当前字符匹配 stack.pop(); }else{ //左右括号不匹配 return false; } } } if(stack.empty()){ return true; }else{ return false; } } }
逆波兰表达式,也叫做后缀表达式。
下图中左边是中缀表达式,中间是其对应的语法树,右边是语法树转成的后缀表达式。
对逆波兰表达式求值的过程是:
如果遇到数字就进栈;
如果遇到操作符,就从栈顶弹出两个数字分别为 num2(栈顶)、num1(栈中的第二个元素);计算num1 运算 num2
class Solution { public int evalRPN(String[] tokens) { Stack<Integer> stack = new Stack<>(); for(String x : tokens) { //不是加减乘法 if(!isOperation(x)) { stack.push(Integer.parseInt(x)); }else{ int num2 = stack.pop(); int num1 = stack.pop(); switch(x) { case "+" : stack.push(num1+num2); break; case "-" : stack.push(num1-num2); break; case "*" : stack.push(num1*num2); break; case "/" : stack.push(num1/num2); break; } } } return stack.pop(); } private boolean isOperation(String opera) { if(opera.equals("+") || opera.equals("-") || opera.equals("*") || opera.equals("/") ) { return true; } return false; } }
栈的压入、弹出序列
思路:
代码展示:
import java.util.*; import java.util.ArrayList; public class Solution { public boolean IsPopOrder(int [] pushA,int [] popA) { //入栈过程中可以出栈 if(pushA.length==0 || popA.length ==0){ return false; } Stack<Integer> stack = new Stack<>(); int j = 0; for(int i = 0;i < pushA.length;i++){ stack.push(pushA[i]); while(j<popA.length && !stack.empty() && stack.peek().equals( popA[j]){ stack.pop(); j++; } } return stack.empty(); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。