本文利用java语言模拟JDK中关于Stack类的实现,下面先对栈的相关概念作简单介绍:
栈(stack)是在表尾进行插入或删除操作的线性表,并将表尾端称作栈顶(top),将表头端称作栈底(bottom);
栈遵循后进先出(last in first out,简称LIFO)的原则,并将删除元素称作出栈,将插入元素称作入栈;
栈有两种存储表示:顺序栈和链栈,下面将分别介绍其实现;
1. 顺序栈和链栈共用的接口
注:所涉及的类均为官方文档中给定的类,故此处注解均摘自官方文档
package org.sky.stack;
public interface Stack<E> {
/**
* Pushes an item onto the top of this stack
* @param item
* @return the item argument
* @author sky
*/
public E push(E item);
/**
* Removes the object at the top of this stack and returns that object as the value of this function
* @return The object at the top of this stack (the last item of the Vector object)
* @author sky
*/
public E pop();
/**
* Tests if this stack is empty
* @return true if and only if this stack contains no items; false otherwise
* @author sky
*/
public boolean empty();
/**
* Returns the 1-based position where an object is on this stack
* @param o
* @return the 1-based position from the top of the stack where the object is located; the return value -1 indicates that the object is not on the stack
* @author sky
*/
public int search(Object o);
/**
* Looks at the object at the top of this stack without removing it from the stack
* @return the object at the top of this stack (the last item of the Vector object)
*/
public E peek();
}
2. 顺序栈
注:底层基于数组实现,但是长度受限
package org.sky.stack;
public class ArrayStack<E> implements Stack<E>{
private int top = -1;
private Object[] objs;
/*
* 构造函数,初始化顺序栈
* @param initSize 初始化栈大小
* @author sky
*/
public ArrayStack(int initSize) {
if(initSize < 0){
try{
throw new Exception("Illegal initSize:"+initSize);
}catch(Exception e){
e.printStackTrace();
}
}
objs = new Object[initSize];
}
/*
* 入栈
* @param item
* @return 栈未满,返回item;否则返回null
* @author sky
*/
public E push(E item){
if(top == objs.length - 1){
try{
throw new Exception("Stack is full!");
}catch(Exception e){
e.printStackTrace();
return null;
}
}
objs[++top] = item;
return item;
}
/*
* 出栈
* @return 栈不空,返回E类型数据;否则返回null
* @author sky
*/
public synchronized E pop(){
if(top == -1){
try{
throw new Exception("Stack is empty!");
}catch(Exception e){
e.printStackTrace();
return null;
}
}
E obj = peek();
top--;
return obj;
}
/*
* 判断当前栈是否为空
* @return 空,返回true;否则,返回false;
* @author sky
*/
public boolean empty(){
return objs.length == 0;
}
/*
* 查找特定元素,返回元素下标;
* @param o
* @return 元素在栈中位置
* @author sky
*/
public int search(Object o){
for(int i = 0; i < objs.length; i++){
if(o.equals(objs[i])){
return i;
}
}
return -1;
}
/*
* 返回栈顶元素,但是不删除
* @return 栈顶元素
* @author sky
*/
public E peek(){
if(top == -1){
try{
throw new Exception("Stack is empty!");
}catch(Exception e){
e.printStackTrace();
return null;
}
}
return (E)objs[top];
}
}
3. 链栈
注:底层采用单链表实现,且长度不受限
package org.sky.stack;
public class LinkedStack<E> implements Stack<E> {
//节点:内部类
public class Node{
//保存本节点的数据
private E data;
//指向下一个节点的引用
private Node next;
public Node(E data, Node next) {
this.data = data;
this.next = next;
}
}
//栈顶指针
private Node top;
//节点数
private int size;
//创建空栈
public LinkedStack(){
top = null;
}
@Override
public E push(E item) {
top = new Node(item, top);
size++;
return top.data;
}
@Override
public synchronized E pop() {
if(empty()){
try{
throw new Exception("empty!");
}catch(Exception e){
e.printStackTrace();
return null;
}
}
Node temp = top;
top = top.next;
size--;
return temp.data;
}
@Override
public boolean empty() {
return top == null;
}
@Override
public int search(Object o) {
Node temp = top;
int tempSize = size;
while(temp != null){
if(temp.data.equals(o)){
return tempSize;
}
temp = temp.next;
tempSize--;
}
return 0;
}
@Override
public E peek() {
if(empty()){
try{
throw new Exception("empty!");
}catch(Exception e){
e.printStackTrace();
return null;
}
}
return top.data;
}
}