一、栈基于数组的实现
用数组实现栈时,将栈底置于数组索引0处,应确定一个泛型数组,数组的容量,以及标识下一个可用数组单元的整型变量top。
栈的操作包括入栈(push),出栈(pop),查看栈顶元素(peek),判断栈是否为空(isEmpty),确定栈内有多少个元素(size)。
实现步骤
- 1.定义栈的接口ADT
public interface StackADT<T> {
public void push(T element);
public T pop( );
public T peek( );
public boolean isEmpty();
public int size();
}
- 2.实现该接口并实现相应的方法(重点)
import java.util.Arrays;
public class ArrayStack<T> implements StackADT<T> {
//数组的默认容量
private final int DEFAULT_CAPACITY = 100;
//标识下一个数组的可用单元变量
private int top;
//泛型数组
private T[] stack;
// 默认容量的构造函数
public ArrayStack() {
top = 0;
//泛型是不能new出对象的,只能将Object转换成泛型
stack = (T[]) new Object[DEFAULT_CAPACITY];
}
// 自定义容量的构造函数
public ArrayStack(int initialCapacity) {
top = 0;
stack = (T[]) new Object[initialCapacity];
}
@Override
/**
* 1.确定栈不是满的
* 2.把数组的top引用设置为要加入到栈中的对象
* 3.增加top的值
*/
public void push(T element) {
if (size() == stack.length) {
//栈满了,扩展栈的容量
expandCapacity();
}
stack[top] = element;
top++;
}
@Override
/**
* 1.确定栈不为空
* 2.减小top计数器
* 3.定义一个临时变量来存储stack[top]的值
* 4.将stack[top]置为null
* 5.返回临时变量
*/
public T pop() {
if (isEmpty()) {
//栈为空,抛出异常,EmptyCollectionException继承RuntimeException
throw new EmptyCollectionException("Stack");
}
top--;
T result = stack[top];
stack[top] = null;
return result;
}
@Override
public T peek() {
if (isEmpty()) {
throw new EmptyCollectionException("Stack");
}
return stack[top - 1];
}
@Override
public boolean isEmpty() {
if (stack[0] == null) {
return true;
}
return false;
}
@Override
public int size() {
return top;
}
public void syso() {
for (int i = 0; i < size(); i++) {
System.out.print(stack[i] + " ");
}
System.out.println("");
}
// 将数组的容量增加一倍
private void expandCapacity() {
stack = Arrays.copyOf(stack, stack.length * 2);
}
}
- 异常类的定义
public class EmptyCollectionException extends RuntimeException {
public EmptyCollectionException(String collection) {
super("the" + collection + "is empty");
}
}
二、栈基于链表的实现
定义一个节点类,该类包含一个两个引用,一个指向链表的下一个结点,另一个指向本结点中存储的元素。
- LinearNode.java
public class LinearNode<T> {
//指向下一个结点的引用
private LinearNode<T> next;
//本结点存储的元素
private T element;
/**
* 创建一个空的节点
*/
public LinearNode() {
next = null;
element = null;
}
/**
* 创建一个节点存储指定元素
*
* @param elem要存储的元素
*/
public LinearNode(T elem) {
next = null;
element = elem;
}
/**
* 返回下一个节点
*
* @return 下一个节点
*/
public LinearNode<T> getNext() {
return next;
}
/**
* 设置下一个节点
*
* @param node要设置的节点
*/
public void setNext(LinearNode<T> node) {
next = node;
}
/**
* 返回节点所指向的内容
*
* @return 存储在该节点下的内容
*/
public T getElement() {
return element;
}
/**
* 设置节点所存储的内容
*
* @param elem将要存储到节点的内容
*/
public void setElement(T elem) {
element = elem;
}
}
- 定义LinkedStack类实现stackADT接口,实现栈中的5个方法(重点)
public class LindedStack<T> implements StackADT<T> {
// 在栈中存储元素的数量
private int count;
// 指向栈顶的指针
private LinearNode<T> top;
public LindedStack() {
count = 0;
top = null;
}
@Override
/**
* 1.创建一个新结点,该结点包含一个引用,指向要放置到栈中的对象
* 2.把新结点的next引用设置为指向当前栈顶(如果栈为空,那它就是null)
* 3.把top引用设置为指向该新结点
* 4.递增栈的元素计数
*/
public void push(T element) {
LinearNode<T> temp = new LinearNode<>(element);
temp.setNext(top);
top = temp;
count++;
}
@Override
/**
* 1.确保栈不为空
* 2.设置一个临时引用等于栈顶元素
* 3.设置top引用为栈顶元素的next引用
* 4.递减栈的元素计数
*/
public T pop() {
if (isEmpty()) {
throw new EmptyCollectionException("Stack");
}
T result = top.getElement();
top = top.getNext();
count--;
return result;
}
@Override
/**
* 1.返回栈顶元素
*/
public T peek() {
if (isEmpty()) {
throw new EmptyCollectionException("stack");
}
return top.getElement();
}
@Override
public boolean isEmpty() {
if (count == 0) {
return true;
} else {
return false;
}
}
@Override
public int size() {
return count;
}
}
以上就是栈基于数组和链表的实现方式,如有不懂,欢迎提问。