1.栈的实现
栈,即FILO(First Int Last Out),它特点是先进后出,栈式内存有很多应用,如编辑器的撤销,函数的调用。首先来看下实现栈需要使用到什么方法。
ArrayStack(int capacity)
有参构造,初始化一个capacity大小的栈式内存。
ArrayStack()
无参构造,初始化默认大小的栈式内存
getSize()
得到栈中元素的个数
getCapacity
得到栈的容量
isEmpty()
判断是否为空
push()
压栈
pop()
出栈
peek()
查看栈顶元素
toString()
这里的栈是基于动态数组实现的,所以先贴出动态数组的代码
/**
* @Author: Cui
* @Date: 2020/7/4
* @Description: 动态数组
*/
public class Array<E> {
private E[] data;
private int size;
//构造函数,传入数组的容量capacity构造Array
public Array(int capacity){
data = (E[])new Object [capacity];
size = 0;
}
//无参构造,默认数组容量为10
public Array(){
this(10);
}
//获取数组中的元素个数
public int getSize(){
return size;
}
//获取数组的容量
public int getCapacity(){
return this.data.length;
}
//返回数组是否为空
public boolean isEmpty(){
return size == 0;
}
//向所有的元素后添加一个新元素
public void addLast(E e){
add(size,e);
}
//向数组首地址添加一个新元素
public void addFirst(E e){
add(0,e);
}
//添加元素
public void add(int index,E e){
if(index < 0 || index > size){
throw new IllegalArgumentException("index<0 or index>size");
}
//动态扩容
if(size == data.length){
resize(2*data.length);
}
for(int i = size-1; i >= index; i--){
data[i+1] = data[i];
}
data[index] = e;
size ++;
}
private void resize(int capacity) {
E[] newData = (E[]) new Object[capacity];
for(int i=0;i<size;i++){
newData[i] = data[i];
}
data = newData;
}
//从数组中删除index位置的元素,返回删除的元素
public E remove(int index){
if(index < 0 || index > size){
throw new IllegalArgumentException("index<0 or index>size");
}
E ret = data[index];
for(int i = index+1 ; i < size ; i++){
data[i-1] = data[i];
}
size--;
//动态缩容
if(size == data.length/4 && data.length/2 != 0){
resize(data.length/2);
}
return ret;
}
//删除数组第一个元素
public E removeFirst(){
return remove(0);
}
//删除数组最后一个元素
public E removeLast(){
return remove(size-1);
}
//查找指定位置的元素
public E get(int index){
return data[index];
}
//获取数组的最后一个元素
public E getLast(){
return get(size-1);
}
//获取数组的第一个元素
public E getFirst(){
return get(0);
}
//查询是否包含
public boolean contains(E e){
for(int i=0;i<size;i++){
if(data[i].equals(e)){
return true;
}
}
return false;
}
//修改指定下标的元素,并返回修改前的元素
public E set(int index,E e){
if(index < 0 || index > size){
throw new IllegalArgumentException("index<0 or index>size");
}
E e1 = data[index];
data[index] = e;
return e1;
}
//查找元素并返回元素的下标,如果不存在则返回-1
public int find(E e){
for(int i = 0; i < size; i++){
if(data[i].equals(e)){
return i;
}
}
return -1;
}
@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append(String.format("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();
}
}
栈的接口
public interface Stack<E> {
//查看栈的长度
int getSize();
//查看栈是否为空
boolean isEmpty();
//压栈
void push(E e);
//出栈
E pop();
//查看栈顶元素
E peek();
}
栈的实现类
/**
* @Author: Cui
* @Date: 2020/7/7
* @Description:
*/
public class ArrayStack<E> implements Stack<E> {
Array<E> array;
public ArrayStack(int capacity){
array = new Array<>(capacity);
}
public ArrayStack(){
array = new Array<>();
}
//获取栈的容量
public int getCapacity(){
return array.getCapacity();
}
//得到栈内元素的长度
@Override
public int getSize() {
return array.getSize();
}
//判断栈是否为空
@Override
public boolean isEmpty() {
return array.isEmpty();
}
//压栈
@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() {
return "ArrayStack{" +
"array=" + array +
"top }";
}
}
测试类
/**
* @Author: Cui
* @Date: 2020/7/4
* @Description:
*/
public class Main {
public static void main(String[] args) {
ArrayStack<Integer> stack = new ArrayStack<>();
for(int i = 0; i < 5; i++ ){
stack.push(i);
}
System.out.println(stack);
System.out.println("弹出:"+stack.pop());
System.out.println(stack);
}
}
2.栈的应用
这是LeetCode上题库的第20题,它使用栈可以很容易的完成
思路:检查一个字符串是否是有效字符串,读取字符串的内容,如果是左括号(“(”,“{”,“[”)就压栈,如果是右括号就查看栈顶元素,看是否与右括号匹配,如果直到字符串结束都一直匹配,并且当读到字符串末尾时,栈为空则字符串有效,否则无效。
import java.util.Stack;
/**
* @Author: Cui
* @Date: 2020/7/7
* @Description:
*/
public class StackSolution {
public boolean isValid(String s){
Stack<Character> stack = new Stack<>();
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 topChar = stack.pop();
if(c == ')' && topChar != '('){
return false;
}
if(c == ']' && topChar != '['){
return false;
}
if(c == '}' && topChar != '{'){
return false;
}
}
}
return stack.isEmpty();
}
}