栈是一种运算受限的线性表,其限制是仅允许在表的一端进行插入和删除运算。它的一端是栈顶,另一端是栈底,元素唯一的进出口是栈顶,它的特点是先进栈的元素后出栈(先进后出);
java中栈的实现有两种方式,数组和链表
数组实现的栈
底层由数组实现,通过操作数组来实现元素的存入和取出,使用top来标识栈顶元素位置。
public class ArrayStack<E> {
/**
* 用于存储元素的数组
*/
private Object[] elements;
/**
* 用于标识栈顶元素的位置
*/
private int top = -1;
/**
* 初始化构造方法,实例化一个大小为10的Object数组
*/
public ArrayStack() {
elements = new Object[10];
}
/**
* 压栈,将元素存入Object数组
* @param var
* @return
*/
public E push(E var) {
//在存入元素之前先检查当前数组空间是否足够
this.resize();
//先将top+1,然后在数组top+1位置上放入元素
elements[++top] = var;
//返回存入的元素
return var;
}
/**
* 出栈
* @return
*/
public synchronized E pop() {
//调用peek方法获取到栈顶元素
Object top = this.peek();
//将栈顶元素设置为null,然后将top-1
this.elements[this.top--] = null;
//返回出栈的栈顶元素
return (E)top;
}
/**
* 查看栈顶元素
* @return
*/
public synchronized E peek() {
//获取到当前栈中元素个数
int var1 = this.size();
if (var1 == 0) {
//如果当前栈中元素个数为0,则抛错栈为空
throw new RuntimeException("栈为空");
} else {
//否则返回栈顶元素
return (E)this.elements[this.top];
}
}
/**
* 判断当前栈是否为空
* @return
*/
public boolean empty() {
//如果当前栈元素个数为0,则为空
return this.size() == 0;
}
/**
* 获取当前栈元素个数
* @return
*/
private int size(){
//栈顶位置+1 = 当前元素个数
return this.top+1;
}
/**
* 重新设置当前数组大小
*/
private void resize(){
//如果当前栈元素个数大于等于数组大小
if(this.size() >= this.elements.length){
//新建一个原有数组两倍大小的数组
Object[] temp = new Object[this.elements.length*2];
//将原有数组复制到新数组中
System.arraycopy(this.elements,0,temp,0,this.elements.length);
//再将当前数组引用替换成新数组
this.elements = temp;
}
}
public static void main(String[] args) {
ArrayStack<String> arrayStack = new ArrayStack<String>();
arrayStack.push("1");
arrayStack.push("2");
arrayStack.push("3");
arrayStack.push("4");
arrayStack.push("5");
arrayStack.push("6");
arrayStack.push("7");
arrayStack.push("8");
arrayStack.push("9");
arrayStack.push("10");
arrayStack.push("11");
System.out.println("栈的大小"+arrayStack.size());
System.out.println("栈的顶部元素:"+arrayStack.peek());
System.out.println("栈的大小"+arrayStack.size());
System.out.println("栈弹出的顶层元素:"+arrayStack.pop());
System.out.println("栈的顶部元素:"+arrayStack.peek());
System.out.println("栈是否为空:"+arrayStack.empty());
}
}
运行结果
链表实现的栈
除了数组可以实现栈数据结构外,链表也可以实现栈,成员变量top(存储栈顶节点)size(当前栈元素个数),LinkedStack中定义内部静态私有类LinkedStackNode,LinkedStackNode中存储前一节点、后一节点、元素。
package stack;
public class LinkedStack<E> {
//标识栈顶节点
private LinkedStack.LinkedStackNode<E> top;
//当前栈元素个数
private int size;
/**
* 压栈,将元素存入Object数组
* @param var
* @return
*/
public E push(E var) {
if(this.size() == 0){
//如果当前栈元素个数为0,说明当前的栈顶为null,新建节点
LinkedStack.LinkedStackNode<E> temp = new LinkedStack.LinkedStackNode<E>(null,var,null);
//栈顶为temp
this.top = temp;
}else{
//否则说明存在top,新建的节点要以top为前一节点
LinkedStack.LinkedStackNode<E> temp = new LinkedStack.LinkedStackNode<E>(this.top,var,null);
//栈顶节点的next设置为temp,建立链表关联
this.top.next = temp;
//将新建的temp节点作为栈顶节点
this.top = temp;
}
//当前栈元素个数+1
this.size++;
return var;
}
/**
* 出栈
* @return
*/
public synchronized E pop() {
//调用peek方法获取到栈顶元素
E currTop = this.peek();
//如果当前栈中只有一个元素
if(this.size() == 1){
//那么弹出后top为null
this.top = null;
}else{
//否则将当前栈顶元素top的前一节点的next修改为null
this.top.prev.next = null;
//栈顶节点等于栈顶节点的prev,这里直接通过修改上一节点的next来移除节点
this.top = this.top.prev;
}
//返回出栈的栈顶元素
this.size--;
return currTop;
}
/**
* 查看栈顶元素
* @return
*/
public synchronized E peek() {
//获取到当前栈中元素个数
int var1 = this.size();
if (var1 == 0) {
//如果当前栈中元素个数为0,则抛错栈为空
throw new RuntimeException("栈为空");
} else {
//否则返回栈顶元素
return this.top.item;
}
}
/**
* 判断当前栈是否为空
* @return
*/
public boolean empty() {
//如果当前栈元素个数为0,则为空
return this.size() == 0;
}
/**
* 获取当前栈元素个数
* @return
*/
private int size(){
return this.size;
}
private static class LinkedStackNode<E>{
//元素值
E item;
//当前节点的的下一节点
LinkedStack.LinkedStackNode<E> next;
//当前节点的上一节点
LinkedStack.LinkedStackNode<E> prev;
public LinkedStackNode(LinkedStackNode<E> prev,E item, LinkedStackNode<E> next) {
this.prev = prev;
this.item = item;
this.next = next;
}
}
public static void main(String[] args) {
LinkedStack linkedStack = new LinkedStack();
linkedStack.push("1");
linkedStack.push("2");
linkedStack.push("3");
System.out.println("栈的大小"+linkedStack.size());
System.out.println("栈的顶部元素:"+linkedStack.peek());
System.out.println("栈的大小"+linkedStack.size());
System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
System.out.println("栈的顶部元素:"+linkedStack.peek());
System.out.println("栈是否为空:"+linkedStack.empty());
System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
linkedStack.push("4");
linkedStack.push("5");
System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
System.out.println("栈弹出的顶层元素:"+linkedStack.pop());
}
}
运行结果