栈
1.栈的使用
public static void main(String[] args) {
Stack<Integer> stack = new Stack<>(); //创建一个Stack对象
stack.push(1);
stack.push(2);
stack.push(3);
System.out.println(stack.peek()); //peek()拿到栈顶元素不删除
System.out.println(stack.pop()); //pop()拿到栈顶元素删除
System.out.println(stack.peek());
stack.pop();
System.out.println(stack.empty());
stack.pop();
//虽然Stack没有isEmpty()方法,但是它继承了Vector类,所以可以使用Vector的方法
System.out.println(stack.isEmpty());
}
2.不可能的出栈顺序
设有一个栈,元素一次进栈的顺序是ABCDE,下列不可能的出栈顺序是?
A:ABCDE
B:BCDEA
C:EABCD
D:EDCBA
对于A来说:进一个出一个得到的出栈顺序就是ABCDE,符合出栈规则
对于B来说:AB先进栈,然后B出栈,CDE依次进然后出,最后A出,因此BCDEA符合出栈规则
对于C来说:先出E说明ABCDE都已经入栈,此时E之后出栈的是D,因此EABCD不符合出栈规则
对于D来说:ABCDE全部入栈后依次出栈,因此EDCBA符合出栈规则
3.中缀表达式转后缀表达式
我们常见的算术表达式都是中缀表达式,而计算机去对算术表达式进行运算时,利用的是后缀表达式也可以称为逆波兰式
。
如何将中缀表达式转为后缀表达式?
独家绝招
:按照从左往右先乘除后加减的顺序对中缀表达式运算符加括号,加完括号之后,将每个算术符移动到离其最近的右括号外,移动结束后,去掉所有的括号,留下的最终表达式就是后缀表达式。
说起来确实很懵,还是通过两道题去实操一下:
1.中缀表达式X = A+B*(C-(D+F))/E转后缀表达式之后是什么?
2.中缀表达式 (a+b)c(d-e/f)转成后缀表达式之后地结果是什么?
画图看一下中缀转后缀的过程:
4.手动实现一个栈
实现栈可以用数组也可以用链表,因为Stack继承了Vector,Vector底层基于数组实现,所以用数组实现栈最好。
利用链表实现栈:采用头插法,插入数据与删除数据的时间复杂度都是O(1);采用尾插法,插入数据与删除数据的时间复杂度都是O(n)。
class MyStack{
private int[] elem;
private int top; //代表数组下标,也代表当前元素的数量
public MyStack(int k) {
this.elem = new int[k];
}
//插入元素
public void push(int val){
//判满
if(isFull()) throw new RuntimeException("栈已满");
this.elem[top] = val;
top++;
//获得插入的元素 elem[top-1];
}
//拿到栈顶元素不删除
public int peek(){
//抛出异常对象也可以 throw new RuntimeException("栈为空")
if(empty()) return -1;
return this.elem[top-1];
}
//拿到栈顶元素并删除
public int pop(){
if(empty()){
throw new RuntimeException("栈已空");
}
int val = this.elem[top-1];
top--;
return val;
/**
* top--;
* return this.elem[top];
*/
}
//判空
public boolean empty(){
return top == 0;
}
//判满
public boolean isFull(){
return top == this.elem.length;
}
}