栈是一个先进后出的数据结构,所以实现栈就抓住栈的该特性,当然使用数组实现栈,需要考虑扩容问题,如果使用链表来实现的话就没有扩容问题了。
一、定义栈的方法接口
这里定义了栈的几个主要方法:
public interface IStack<E> {
/**
* 栈元素大小
* @return
*/
int size();
/**
* 是否为空
* @return
*/
boolean empty();
/**
* 压栈
* @param item
*/
void push(E item);
/**
* 弹栈
* @return
*/
E pop();
/**
* 查看栈顶元素
* @return
*/
E peek();
}
二、实现
/**
* 通过数组实现一个栈
* @param <E>
*/
public class ArrayStack<E> implements IStack<E> {
// 默认容量
private static final int DEFAULT_CAPACITY = 10;
// 保存元素的数组
private E[] data;
// 元素数量
private int size;
// 栈顶指针 索引
private int top;
public ArrayStack(){
this(DEFAULT_CAPACITY);
}
public ArrayStack(int capacity){
this.size = 0;
this.top = -1;
this.data = (E[]) new Object[capacity];
}
/**
* 栈元素大小
* @return
*/
@Override
public int size() {
return size;
}
/**
* 是否为空
* @return
*/
@Override
public boolean empty() {
return size == 0;
}
/**
* 压栈
* @param item
*/
@Override
public void push(E item) {
if(data.length == size){
// grow 扩容
grow(2 * size);
}
data[++top] = item;
size ++;
}
private void grow(int capacity){
if(capacity <= DEFAULT_CAPACITY )
return;
data = Arrays.copyOf(data, capacity);
}
/**
* 弹栈
* @return
*/
@Override
public E pop() {
if(size == 0){
throw new EmptyStackException();
}
size --;
if(size < (data.length>>1)){
grow(data.length>>1);
}
return data[top--];
}
/**
* 查看栈顶元素
* @return
*/
@Override
public E peek() {
if(size == 0){
throw new EmptyStackException();
}
return data[top];
}
public static void main(String[] args) {
IStack stack = new ArrayStack();
for(int i=0; i<10; i++){
stack.push(i+1);
}
System.out.println("弹出元素:"+stack.pop());
System.out.println("弹出元素:"+stack.pop());
for (int i = 0; i < 8; i++) {
System.out.println("弹出剩余元素:"+stack.pop());
}
}
}
测试结果:
弹出元素:10
弹出元素:9
弹出剩余元素:8
弹出剩余元素:7
弹出剩余元素:6
弹出剩余元素:5
弹出剩余元素:4
弹出剩余元素:3
弹出剩余元素:2
弹出剩余元素:1