栈的特点:先进后出,基本操作包括:进栈push,出栈pop,查看栈顶元素peek,判断栈是否为空isEmpty,获取栈中元素的个数getSize
定义一个Stack接口,记下上述操作,定义一个Array类实现自定义的数组类的操作,最后再来一个ArrayStack类,实现Stack接口,复用Array类中的方法就可以轻松实现栈
由于是使用自定义数组类实现的栈,无论是进栈还是出栈,都是只需要对数组类的最后一个元素进行操作,因此进栈/出栈/获取栈顶元素的时间复杂度都为O(1),具体代码如下:
Stack接口
public interface Stack<E> {
public void push(E e);
public E pop();
public E peek();
public int getSize();
public boolean isEmpty();
}
数组类
public class Array<E> {
private E data[];
private int size;
/**
* 构造函数,传入数组的容量capacity构建数组
* @param capacity 数组容量
*/
public Array(int capacity) {
this.data = (E[])new Object[capacity];
size = 0;
}
/**
* 默认构造方法,容量为10
*/
public Array() {
this(10);
}
/**
* 获取数组中元素的个数
* @return 元素个数
*/
public int getSize() {
return this.size;
}
/**
* 获取数组中的容量大小
* @return 容量
*/
public int getCapacity() {
return this.data.length;
}
/**
* 判断数组是否为空
* @return 是否为空
*/
public boolean isEmpty() {
return this.size == 0;
}
/**
* 在所有元素后插入一个新的元素e
* @param e 要插入的元素
*/
public void addLast(E e) {
add(this.size,e);
}
/**
* 在数组头插入一个元素e
* @param e 要插入的元素
*/
public void addFirst(E e) {
add(0,e);
}
/**
* 在指定索引位置插入元素e
* @param index 索引值
* @param e 元素值
*/
public void add(int index,E e) {
if(this.size >= this.data.length * 0.75) {
this.reSize(this.data.length * 2);
}
/*
* if(this.size == this.data.length) { throw new
* IllegalArgumentException("参数错误,元素个数大于数组容量"); }
*/
if(index < 0 || index > this.size) {
throw new IllegalArgumentException("参数错误,索引越界");
}
for(int i = this.size - 1; i >= index; i--) {
data[i + 1] = data[i];
}
data[index] = e;
size ++;
}
/**
* 获取指定索引位置的元素值
* @param index
* @return
*/
public E get(int index) {
if(index < 0 || index >= size) {
throw new IllegalArgumentException("索引越界");
}
return this.data[index];
}
/**
* 获取第一个元素
* @return
*/
public E getFirst() {
return get(0);
}
public E getLast() {
return get(getSize() - 1);
}
/**
* 设置指定索引位置的元素值为e
* @param index
* @param e
*/
public void set(int index,E e) {
if(index < 0 || index >= size) {
throw new IllegalArgumentException("索引越界");
}
this.data[index] = e;
}
/**
* 判断数组中是否包含元素e
* @param e
* @return
*/
public boolean contains(E e) {
for(int i = 0; i < size; i++) {
if(this.data[i].equals(e)) {
return true;
}
}
return false;
}
/**
* 返回查找的元素e的索引值
* @param e
* @return
*/
public int find(E e) {
for(int i = 0; i < size; i++) {
if(this.data[i].equals(e)) {
return i;
}
}
return -1;
}
/**
* 删除数组中指定索引位置的元素,返回被删除的元素
* @param index
* @return
*/
public E remove(int index) {
if(index < 0 || index >= size) {
throw new IllegalArgumentException("索引越界");
}
if(this.size <= this.data.length / 3) {
this.reSize(this.data.length / 2);
}
E res = data[index];
for(int i = index; i < size; i++) {
data[i] = data[i+1];
}
data[size] = null;
size--;
return res;
}
/**
* 删除数组中的第一个元素,返回被删除的元素
* @return
*/
public E removeFirst() {
return remove(0);
}
/**
* 删除数组中最后一个元素,返回被删除的元素
* @return
*/
public E removeLast() {
return remove(size - 1);
}
/**
* 删除数组中的元素e
* @param e
*/
public void removeElement(E e) {
int index = find(e);
if(index != -1) {
remove(index);
}
}
private void reSize(int capacity) {
E[] newData = (E[])new Object[capacity];
for(int i = 0; i < this.size; i++) {
newData[i] = this.data[i];
}
this.data = newData;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Array : catacity = " + this.getCapacity() + ", size = " + this.getSize() + "; [ ");
for(int i = 0; i < size ; i++) {
sb.append(data[i]);
if( i != size - 1) {
sb.append(", ");
}
}
sb.append(" ]");
return sb.toString();
}
}
栈类(底层用数组类实现):
public class ArrayStack<E> implements Stack<E> {
private Array<E> array;
public ArrayStack(int capacity) {
array = new Array<>(capacity);
}
public ArrayStack() {
array = new Array<>();
}
@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();
}
public int getCapacity() {
return array.getCapacity();
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Stack : [ ");
for(int i = 0; i < array.getSize(); i++) {
sb.append(array.get(i));
if( i != array.getSize() - 1) {
sb.append(", ");
}
}
sb.append(" ] top");
return sb.toString();
}
}