前言:
上篇我们讲了链表,这次我们来学一个新的存储结构----栈。
目录
1.栈的概念:
栈:一种特殊的线性表。(线性表是逻结构),其允许在固定一端进行插入和删除的操作。进行插入和删除操作的一端称为栈顶,另一端称为栈底。
栈中的数据元素遵循先进后出的原则(Last In First Out)。----就如给弹夹装子弹一样,先装的子弹最后被打出来。
压栈:栈的插入操作。
出栈:栈的删除操作。
2.栈的模拟实现:
因为栈只在一端进行插入和删除,栈中数据元素遵循的先进后出,这样用数组会比较容易,但是它也可以用链表,这里我们用数组来模拟实现栈。
2.1:模拟构建栈
2.2:入栈
public void push(int data){
//要先判断栈是否是满的
if(isFull()){
//满了就要进行扩容
this.elem= Arrays.copyOf(this.elem,
this.elem.length*2);
}
//未满。就要数据元素进栈
this.elem[usedSize]=data;
//记录数据个数加
usedSize++;
}
/**
* 返回true 表示满
* @return
*/
public boolean isFull(){
return usedSize>=elem.length;
}
}
2.3:出栈
public int pop(){
//要判断栈是否为空
if(empty()){//栈空
throw new EmptyWrongException("此栈为空,无法删除");
}//栈不空,删除元素
// usedSize--;//记录有效元素个数减。
return this.elem[--usedSize];
}
/**
* usedSize==0,表示栈中元素个数为0,返回true
* @return
*/
public boolean empty(){
return usedSize==0;
}
其实并没有删除元素,只是将记录有效元素的个数减减。
2.4:获取栈顶元素
3.栈的使用
方法 | 功能 |
Stack() | 构造一个空的栈 |
E push(E e) | 将e入栈,并返回e |
E pop(); | 将栈顶元素出栈并返回 |
E peek() | 获取栈顶元素(不删除) |
int size() | 获取栈中有效元素的个数 |
boolean empty() | 检测栈是否为空 |
4.栈的编程题:
4.1:括号匹配
https://leetcode.cn/problems/valid-parentheses/
class Solution {
public boolean isValid(String s) {
Stack<Character> stack1 = new Stack<>();
for(int i = 0; i < s.length();i++) {
char ch = s.charAt(i);//用字符ch记录遍历的字符
//左括号进栈
if(ch == '(' || ch == '[' || ch == '{') {
stack1.push(ch);
}else {//字符未遍历完,但栈空
if(stack1.empty()) {
return false;
}
char ch2 = stack1.peek();//ch2是栈顶元素,只能
//左括号,因为只让括号进栈
if(ch2 == '[' && ch == ']'
|| ch2 == '(' && ch == ')'
|| ch2 == '{' && ch == '}') {
stack1.pop();//匹配就出栈
}else{
return false;
}
}
}
//这里是字符串遍历完,要看看栈是否为空
if(!stack1.empty()){
return false;
}
return true;
}
}
4.2:逆波兰表达式求值
https://leetcode.cn/problems/evaluate-reverse-polish-notation/
看到这个题目,是不是有点懵逼,什么叫逆波兰。
逆波兰其实也叫后缀表达式,那什么又叫后缀表达式。莫急莫急,让我们看看案例
应该大家都懂了,那我们来看看题。
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 num1=stack.pop();//记录出栈得元素
int num2=stack.pop();
switch (x){
case "+":
stack.push(num2+num1);
break;
case "-":
stack.push(num2-num1);
break;
case "/":
stack.push(num2/num1);
break;
case "*":
stack.push(num2*num1);
break;
}
}
}
return stack.pop();
}
protected boolean isoperation(String x){
if(x.equals("*")||x.equals("/")||
x.equals("+")||x.equals("-")){
return true;
}
return false;
}
}
总结:
以上就是我总结得栈的知识点和编程题,若有遗漏,希望各位老铁,留言补充,若感觉不错,希望各位铁子可以一键三连。感谢