五、栈(Stack)
栈(Stack)是一种后进先出的数据结构(LIFO:last in first out),只允许访问栈中的第一个数据项:即最后插入的数据项。移除这个数据项之后,才能看到第二个数据项,以此类推。
往栈中存入数据称之为压栈(push),移除数据称之为弹栈(pop),此外通常还提供查看栈顶元素的peek方法,此方法可以拿到栈顶元素的值,但是并不会将其移除。
java.util.Stack就是JDK提供的一种对栈的实现,这个实现是基于数组的,由于栈非常简单,我们没有必须要分析源码,直接按照以下方法提供一个相同的自己的实现,此外,我们也可以基于链表来实现一个栈。
1、基于数组的栈的实现
关于基于数组的栈的实现,只有一点值得注意的地方,其是LIFO,但是我们在使用数组的时候,并不需要每次都将元素插入数组的第一个位置,然后将之前的所有元素后移一个位置,只要用一个变量记住最后一个添加的元素的位置即可,当弹栈时,直接返回这个位置上的数字即可。
下面是代码实现:
public class SimpleArrayStack<V> {
private Object[] array = null;
private int size = 0;
private static final int DEFAULR_INITIAL_SIZE = 10;
private int capacity = 0;
public SimpleArrayStack() {
this(DEFAULR_INITIAL_SIZE );
}
public SimpleArrayStack(int initial_size) {
super();
this.capacity = initial_size;
array = new Object[initial_size];
}
/**
* 压栈
*/
public void push(V v) {
int index = size++;
if (index > capacity) { // 扩容
int new_capacity = capacity + capacity >> 1;
if (new_capacity <= 0) {
new_capacity = Integer.MAX_VALUE;
}
array = Arrays.copyOf(array, new_capacity);
}
array[index] = v;
}
/**
* 弹栈
*/
public V pop() {
if (size < 1) {
throw new IllegalStateException("栈内没有元素");
}
V result = (V)array[--size];
array[size] = null;
return result ;
}
/**
* 获取栈顶值
*/
public V peek() {
if (size < 1) {
throw new IllegalStateException("栈内没有元素");
}
return (V)array[size - 1];
}
/**
* 获取栈大小
*/
public int getSize() {
return size ;
}
}
2、基于链表的栈的实现
基于链表的Stack尤为简单,我们可以使用SingleLinkList来实现,实际上就是一种委派:一个数据结构可以在另外一个数据结构的基础上编写。
下面是代码实现:
public class SimpleLinkedListStack<V> {
private SingleLinkList<V> list =new SingleLinkList<V>();
public void push(V v){
list.addFirst(v);
}
public V pop(){
return list.removeFirst();
}
public V peek(){
return list.getFirst();
}
public int getSize(){
return list.getSize();
}
}