栈的定义
栈是只允许一端进行操作的线性表。
push:入栈,往栈中添加元素,
pop:出栈,只能移除栈顶元素
这里的栈是数据结构,栈空间是个栈的空间
栈的接口设计(基本操作)
所以栈最常用的操作就是在栈顶,因为只有在栈顶才能添加删除。
栈的顺序存储结构
让动态数组变成栈类的一部分。若采用继承的方式,对外接口就多了,那栈就会调用ArrayList其他方法,比如在指定位置添加元素,这样不符合栈的特性。
public class Stack <E> {
private List<E> list = new ArrayList<>();
public void clear(){
//调用数组里的clear方法
list.clear();
}
public boolean isEmpty(){
//调用数组里的检查是否为空的方法
return list.isEmpty();
}
public void push(E element){
list.add(element);
}
public E pop(){
return list.remove(list.size() - 1);
}
public E top(){
return list.get(list.size() - 1);
}
}
栈的链式存储结构
同样的,采用链式存储的时候在stack类类里把链表作为他的成员即可。
private List list = new LinkedList<>();
java官方源码
区别在于里面的源码的方法加了线程安全,但是思想是一样的。
栈的应用-浏览器页面的前进后退
打开浏览器,一次访问 baidu.com qq.com taobao.com,后退一次到qq.com的界面,输入地址访问jd.com,这时候,taobao.com就被移除栈了,栈里只剩下 baidu.com qq.com jd.com。
此时到了jd.com的页面从jd.com后退两次,到baidu.com,输入360.com,这时栈里就只剩下了baidu.com jd.com。
所以浏览器的前进后退只能退一格或进一格,不能跨两个格。
但是为什么可以前进和后退?因为它设置了两个栈a,b,依次输入jd.com qq.com baidu.com两者能不停地前后前进后退,后退时把a弹出的栈顶元素依次放了另一个栈b,前进时又把b的栈顶元素放入a。
如果这时要输入新的页面,就把该元素放入a的栈顶元素。
类似的,撤销功能也是利用了栈……
练习、有效的括号
思路:
1.遇到左字符,把左字符入栈;
2.遍历到右字符时 (此时栈顶元素是最后一个左字符),将栈顶元素弹出与之比较,若匹配就没问题,说明两个是对应的;若不匹配,括号无效
3.若一开始遇到了右字符,说明栈是空的,字符无效
4.最后 比完了,栈为空有效;栈不为空,括号无效
法1
class Solution {
public boolean isValid(String s) {
while(s.contains("{}") || s.contains("[]") || s.contains("()")){
s=s.replace("{}"," “);
s=s.replace(”[]"," “);
s=s.replace(”()"," ");
}
return s.isEmpty();
}
}