线性表举例之一:栈
栈(Stack)是一种数据结构,是只能在某一端插入和删除的特殊线性表。它按照后进先出/先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据,即最后一个数据被第一个读出来。在栈中,允许进行插入和删除操作的一端称为栈顶(top),另一端为栈底(bottom);栈底固定,而栈顶 浮动;栈中元素个数为零时称为空栈。插入一般称为进栈(Push),删除则称为退栈(Pop)。
栈可以用来在函数调用的时候存储断点,做递归时要用到栈。
在Java语言中,java.util包里有栈的实现类Stack,是Vector的子类,它通过五个操作对类 Vector 进行了扩展 ,允许将向量视为堆栈。它提供了通常的 push 和 pop 操作,以及取栈顶点的 peek 方法、测试栈是否为空的 empty 方法、在栈中查找项并确定到栈顶距离的 search 方法。
一、数组实现的栈,能存储任意类型的数据
/**
* Java : 数组实现的栈,能存储任意类型的数据
*/
import java.lang.reflect.Array;
public class GeneralArrayStack<T> {
private static final int DEFAULT_SIZE = 12;
private T[] mArray;
private int count;
public GeneralArrayStack(Class<T> type) {
this(type, DEFAULT_SIZE);
}
public GeneralArrayStack(Class<T> type, int size) {
// 不能直接使用mArray = new T[DEFAULT_SIZE];
mArray = (T[]) Array.newInstance(type, size);
count = 0;
}
// 将val添加到栈中
public void push(T val) {
mArray[count++] = val;
}
// 返回“栈顶元素值”
public T peek() {
return mArray[count-1];
}
// 返回“栈顶元素值”,并删除“栈顶元素”
public T pop() {
T ret = mArray[count-1];
count--;
return ret;
}
// 返回“栈”的大小
public int size() {
return count;
}
// 返回“栈”是否为空
public boolean isEmpty() {
return size()==0;
}
// 打印“栈”
public void PrintArrayStack() {
if (isEmpty()) {
System.out.printf("stack is Empty\n");
}
System.out.printf("stack size()=%d\n", size());
int i=size()-1;
while (i>=0) {
System.out.println(mArray[i]);
i--;
}
}
public static void main(String[] args) {
String tmp;
GeneralArrayStack<String> astack = new GeneralArrayStack<String>(String.class);
// 将10, 20, 30 依次推入栈中
astack.push("10");
astack.push("20");
astack.push("30");
// 将“栈顶元素”赋值给tmp,并删除“栈顶元素”
tmp = astack.pop();
System.out.println("tmp="+tmp);
// 只将“栈顶”赋值给tmp,不删除该元素.
tmp = astack.peek();
System.out.println("tmp="+tmp);
astack.push("40");
astack.PrintArrayStack(); // 打印栈
}
}
二、Java的 Collection集合中自带的"栈"(stack)的示例
Stack源码
package java.util;
public class Stack<E> extends Vector<E> {
public Stack() {
}
public E push(E item) { <span style="color:#ff0000;">//push操作,进栈</span>
addElement(item);
return item;
}
public synchronized E pop() { <span style="color:#ff0000;">//pop操作,退栈</span>
E obj;
int len = size();
obj = peek();
removeElementAt(len - 1);
return obj;
}
public synchronized E peek() { <span style="color:#ff0000;">//取得栈顶元素</span>
int len = size();
if (len == 0)
throw new EmptyStackException();
return elementAt(len - 1);
}
public boolean empty() { <span style="color:#ff0000;">//判断栈是否为空</span>
return size() == 0;
}
public synchronized int search(Object o) { <span style="color:#ff0000;">//查找</span>
int i = lastIndexOf(o);
if (i >= 0) {
return size() - i;
}
return -1;
}
private static final long serialVersionUID = 1224463164541339165L;
}
Vector源码
栈的应用举例