栈的概念
栈是一种后进先出的数据结构
Last In First Out (LIFO)
栈的应用
无所不在的Undo操作(撤销)
栈要实现的接口
datastructure.stack.datastructure.linkedList.Stack
public interface datastructure.stack.datastructure.linkedList.Stack {
int getSize();
boolean isEmpty();
void push(E e);
E pop();
E peek();
}
栈所基于的可变数组类
public class datastructure.array.Array{
// 泛型不能存放基本的数据类型
private E[] data;
private int size;
// 有参数构造函数
public datastructure.array.Array(int capacity){
// 泛型数组,由于历史遗留原因,必须绕一个圈
data = (E[])new Object[capacity];
size = 0;
}
// 无参构造函数
public datastructure.array.Array(){
this(10);
}
// 获取数组中个元素个数
public int getSize(){
return this.size;
}
// 获取数组的容量
public int getCapacity(){
return this.data.length;
}
// 返回数组是否为空
public boolean isEmpty(){
return this.size == 0;
}
// 在第index个位置插入一个新的元素e
public void add(int index, E e){
if(index < 0 || index > size){
throw new IllegalArgumentException("AddLast failed. require index>=0 and <=?");
}
// 扩容数组,如果
if(size == data.length){
E[] newData = (E[])new Object[data.length * 2];
for(int i = 0; i < index;i++){
newData[i] = data[i];
}
newData[index] = e;
for(int i = index ; i < size;i++){
newData[i+1] = data[i];
}
data = newData;
} else {
for(int i = size - 1; i >= index; i--)
data[i + 1] = data[i];
data[index] = e;
}
size ++;
}
// 向所有元素后面添加一个新元素
public void addLast(E e){
this.add(size, e);
}
// 向所有元素前面添加一个新元素
public void addFirst(E e){
this.add(0, e);
}
// 获取index索引位置的元素
public E get(int index) {
if(index < 0 || index >= size)
throw new IllegalArgumentException("Get failed, Index is illegal.");
return data[index];
}
public E getLast(){
return get(size - 1);
// 不用data[size - 1] 是因为没有异常处理
}
public E getFirst(){
return get(0);
}
// 修改index索引位置的元素
public void set(int index, E e) {
if(index < 0 || index >= size)
throw new IllegalArgumentException("Set failed, Index is illegal");
data[index] = e;
}
// 查找数组中是否含有元素e,
public boolean contains(E e){
for(int i=0;i < size;i++){
// 两个对象之间值的比较用equals
if(data[i].equals(e))
return true;
}
return false;
}
// 查找数组中是否含有元素e元素的索引,如果查到,返回查询到的第一个索引值,否则返回-1
public int find(E e){
for(int i=0;i < size;i++){
if(data[i].equals(e))
return i;
}
return -1;
}
// 删除指定位置的元素,防止复杂度的震荡,
// 懒缩容。
public E remove(int index){
if(index < 0 || index >= size)
throw new IllegalArgumentException("Remove failed, Index is illegal");
E ret = data[index];
if(size-1 == data.length / 4 && data.length / 2 != 0){
// 懒惰缩容,防止复杂度震荡,当数组的size小于capacity的四分之一才开始缩容
E[] newData = (E[])new Object[data.length / 2];
for(int i = 0; i < index; i++){
newData[i] = data[i];
}
for(int i = index; i < size - 1;i++){
newData[i] = data[i+1];
}
data = newData;
} else {
for(int i = index; i < size-1;i ++)
data[i] = data[i+1];
}
size --;
// data[size] = null; // 回收内存,可选
// // loitering objects != memory leak
return ret;
}
// 删除的快捷方法
public E removeFirst(){
return remove(0);
}
public E removeLast(){
return remove(size -1);
}
// 删除指定的元素e
public void removeElement(E e){
int index = find(e);
if(index != -1){
remove(index);
}
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
// res.append(String.format("datastructure.array.Array: size = %d , capacity = %d\n", size, data.length));
res.append(String.format("datastructure.array.Array: size = %d , capacity = %d\n", size, data.length));
res.append('[');
for(int i = 0; i < size; i++) {
res.append(data[i]);
if(i != size - 1)
res.append(", ");
}
res.append(']');
return res.toString();
}
private void resize(int newCapacity){
E[] newData = (E[])new Object[newCapacity];
for(int i = 0; i < size; i++){
newData[i] = data[i];
}
data = newData;
}
}
栈的实现ArrayStack
public class datastructure.array.ArrayStack implements datastructure.stack.datastructure.linkedList.Stack{
datastructure.array.Array array;
public datastructure.array.ArrayStack(int capacity){
array = new datastructure.array.Array<>(capacity);
}
public datastructure.array.ArrayStack(){
array = new datastructure.array.Array<>();
}
@Override
public int getSize(){
return array.getSize();
}
@Override
public boolean isEmpty(){
return array.isEmpty();
}
public int getCapacity(){
return array.getCapacity();
}
@Override
public void push(E e){
array.addLast(e);
}
@Override
public E pop(){
return array.removeLast();
}
@Override
public E peek(){
return array.getLast();
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("datastructure.stack.datastructure.linkedList.Stack: [");
for(int i = 0; i < array.getSize(); i++){
res.append(array.get(i));
if(i != array.getSize() - 1)
res.append(", ");
}
res.append("] top");
return res.toString();
}
}
栈的使用场景举例,判断括号的闭合合法性(假设字符串中只包含()[]{})
import java.util.datastructure.stack.datastructure.linkedList.Stack;
class datastructure.datastructure.linkedList.Solution {
public boolean isValid(String s) {
datastructure.array.ArrayStack stack = new datastructure.array.ArrayStack<>();
for(int i = 0;i < s.length(); i++){
char c = s.charAt(i);
if(c == '(' || c == '[' || c == '{'){
stack.push(c);
} else {
if(stack.isEmpty())
return false;
char top = stack.pop();
if(c == ')' && top != '('){
return false;
}
if(c == ']' && top != '['){
return false;
}
if(c == '}' && top != '{'){
return false;
}
}
}
return stack.isEmpty();
}
public static void main(String[] args){
System.out.println((new datastructure.datastructure.linkedList.Solution()).isValid("[](){}"));
}
}