栈Stack
一 栈:先进后出
一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵守后进先出LIFO(Last In First Out)的原则。
Stack<Integer> stack=new Stack<>();
public static void main(String[] args) {Stack<Integer> stack=new Stack<>();//入栈pushstack.push(12);stack.push(23);stack.push(34);//出栈pop 弹出栈顶元素Integer x=stack.pop();System.out.println(x);Integer y=stack.pop();System.out.println(y);//peek()获取栈顶元素不删除int ret=stack.peek();System.out.println(ret);if(stack.empty()){System.out.println("栈空");}else {System.out.println("栈不为空");}System.out.println(stack.size());}
}
2)栈的模拟实现
数组模拟栈的实现
import java.util.Arrays;public class MyStack {//栈的模拟实现private int []elem;private int usedSize;private static final int DEFAULT_CAPACITY=10;public MyStack(){this.elem= new int[DEFAULT_CAPACITY];}public void push(int val){if(ifFull()){//扩容elem= Arrays.copyOf(elem ,2*elem.length);}elem[usedSize]=val;usedSize++;}//删除 直接--public int pop(){if(ifFull()){//栈满抛异常throw new EmptyException();}int oldValue=elem[usedSize-1];usedSize--;return oldValue;}public int peek(){if(ifFull()){throw new EmptyException();}return elem[usedSize-1];}public boolean isEmpty(){if(usedSize==0){return true;}else {return false;}//retutn useSize==0;}//判断数组是否填满,满则扩容public boolean ifFull(){return usedSize==elem.length;}}
定义异常
public class EmptyException extends RuntimeException{//定义异常public EmptyException() {}public EmptyException(String message) {super(message);}
}
例题1:逆序打印链表(反转链表)
把链表存放在栈中(打印出元素的值)
public ListNode reverseList(ListNode head) {Stack<ListNode> stack=new Stack<>();if(head==null) return null;ListNode cur=head;while(cur!=null){stack.push(cur);cur=cur.next;}//返回元素的值while(!stack.empty()){System.out.println(stack.pop().val+" ");}}
void printList(Node head){
if(null != head){
printList(head.next);
System.out.print(head.val + " ");
}
例题2 括号匹配
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 c=stack.pop();//先取出来如果匹配在删除char c=stack.peek();if(c=='('&&ch==')'||c=='{'&&ch=='}'||c=='['&&ch==']'){stack.pop(); //不能直接返回还要往下匹配 // return true;}else{return false;}}}//匹配完后还有剩余if(!stack.empty()){return false;}return true;}
}
例题3 逆波兰表达式求值
boolean/s.equals()/parseInt()
class Solution {public int evalRPN(String[] tokens) {Stack<Integer> stack=new Stack<>();//字符串数组,每一个元素是字符串for( String s:tokens){if(!isOperation(s)){//数字stack.push(Integer.parseInt(s));}else{int nums2=stack.pop();int nums1=stack.pop();switch(s){case"+":int ret=nums1+nums2;stack.push(ret);break;case"-":ret=nums1-nums2;stack.push(ret);break;case"*":ret=nums1*nums2;stack.push(ret);break;case"/":ret=nums1/nums2;stack.push(ret);break;}}}return stack.pop();}//字符串比价public boolean isOperation(String s){if(s.equals("+")||s.equals("-")||s.equals("*")||s.equals("/")){return true;}return false;}
}
问题
if(tokens[i].charAt(0) != '+' && tokens[i].charAt(0) != '-' && tokens[i].charAt(0) != '*' && tokens[i].charAt(0) != '/')不能这样写!
当尝试使用 tokens[i].charAt(i)
时,实际上是在试图访问 tokens
数组第 i
个元素所对应的字符串中的第 i
个字符。这通常是不正确的,尤其是当字符串长度小于 i
时(例如,单字符数字字符串 "1"),这会导致 StringIndexOutOfBoundsException
异常。
"-11".charAt(0)
返回的是 '-'
,即减号字符,而不是 -11
或者其他。
switch (expression) {case value1:// 当 expression 的值等于 value1 时执行的代码块break;case value2:// 当 expression 的值等于 value2 时执行的代码块break;// 可以有任意数量的 case 语句default:// 如果没有 case 匹配,则执行这里的代码块
}