Stack的实现
栈(Stack)是一种只能在一个位置进行操作的,LIFO(后进先出)的抽象数据类型。栈的基本操作通常是两种:pop(出栈)和push(入栈),出栈即删除栈顶元素并返回其值,入栈即将元素插入栈顶。
功能描述
- pop()和push();
- isEmpty(),判断栈当前是否为null;
- size() 返回当前栈空间大小。
代码实现
采用链表和数组实现。
链表实现
如下,采用链表实现一个栈,MyStack保存栈顶节点的引用,每一个节点又包含对下一个节点的引用。
package com.yam.base;
import java.util.NoSuchElementException;
/**
* 使用链表实现的栈结构
* @author: Ympery
* @date: 2017/3/13 16:30.
*/
public class MyStackList<AnyType> {
/**
* 栈顶元素
*/
private Node<AnyType> top;
/**
* 栈当前空间大小
*/
private int theSize;
public MyStackList() {
top = new Node<>(null, null);
theSize = -1;
}
/**
* 返回栈当前空间大小
* @return
*/
public int size() { return ++theSize; }
/**
* 判断栈是否为空
* @return
*/
public boolean isEmpty() {
return theSize == -1;
}
/**
* 压栈:讲一个元素压入栈顶
* @param newVal 要压入栈顶的元素
* @return
*/
public boolean push(AnyType newVal) {
pushNode(newVal);
return true;
}
/**
* 出栈:取出栈顶元素
* @return
*/
public AnyType pop() {
return popNode().data;
}
/**
* 放入栈顶节点
* @param newVal
*/
private void pushNode(AnyType newVal) {
if (-1 == theSize)
top.data = newVal;
else {
Node<AnyType> newNode = new Node<>(newVal, top);
top = newNode;
}
theSize++;
}
/**
* 取出栈顶节点
* @return
*/
private Node<AnyType> popNode() {
if (-1 == theSize)
throw new NoSuchElementException();
Node<AnyType> popNode = top;
top = top.next;
theSize--;
return popNode;
}
/**
* 栈中的元素,包含数据和指向下一个元素的指针
* @param <AnyType>
*/
private class Node<AnyType> {
public Node(AnyType d, Node<AnyType> n) {
data = d;
next = n;
}
private AnyType data;
private Node<AnyType> next;
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
MyStackList<Character> stack = new MyStackList<>();
char c = 'a';
for (int i = 0; i < 15; i++)
stack.push(c++);
while (!stack.isEmpty())
System.out.print(stack.pop() + " ");
System.out.println("当前元素个数:" + stack.size());
}
}
数组实现
数组实现模仿了ArrayList的add方法,避免了对链表的维护。
package com.yam.base;
/**
* 使用数组实现的栈结构
* @author: Ympery
* @date: 2017/3/13 17:48.
*/
public class MyStackArray<AnyType> {
private final static int DEFAULT_CAPACITY = 1;
/**
* 栈空间大小标记,为-1时表示栈空
*/
private int theSize;
private AnyType[] theItems;
public MyStackArray() { clear(); }
/**
* 清理/初始化栈
*/
public void clear() {
theSize = -1;
ensureCapacity(DEFAULT_CAPACITY);
}
public boolean isEmpty() { return -1 == theSize; }
public int size() { return theSize + 1; }
/**
* 确保栈空间
*/
public void ensureCapacity(int newCapacity) {
if (newCapacity < theSize + 1)
return;
AnyType[] old =theItems;
theItems = (AnyType[]) new Object[newCapacity];
for (int i = 0; i < size(); i++) {
theItems[i] = old[i];
}
}
/**
* 压栈
* @param val
*/
public void push(AnyType val) {
if (theItems.length == size())
ensureCapacity(2 * size());
theItems[++theSize] = val;
}
/**
* 出栈
* @return
*/
public AnyType pop() {
AnyType top = theItems[theSize--];
// 防止连续出栈造成内存浪费
if (theItems.length / 4 > theSize)
ensureCapacity(theItems.length / 2);
return top;
}
/**
* 测试
* @param args
*/
public static void main(String[] args) {
MyStackArray<Character> stack = new MyStackArray<>();
char c = 'a';
for (int i = 0; i < 15; i++)
stack.push(c++);
while (!stack.isEmpty())
System.out.print(stack.pop() + " ");
System.out.println("当前元素个数:" + stack.size());
}
}