一、前言
1.1 栈的概念
在之前的集合框架图示中栈(Stack)这个类是基于顺序表Vector来实现的,本质上是一种特殊的线性表,只允许在固定的一端进行插入和删除元素操作,进行数据插入和操作的一端称为栈顶,另一端称为栈底。
1.2栈的特点
栈中的元素具有后进先出的特点。
1.3 栈的操作
线性表可以支持增删改查各种操作,栈相当于对线性表的功能进行了限制.基本操作就是以下三种:
1.入栈(把元素通过栈顶往下放)
2.出栈(把栈顶元素删除掉)
3.取栈顶元素(获取到最上面的元素)
接下来我们就来基于顺序表和链表两种方式来实现一个栈:
二、栈的实现
2.1 基于顺序表实现栈
public class MyStackByArrayList {
//基于一个顺序表/链表实现
private int[] array=new int[100];
//有效元素[0,size) 区间中的元素是栈中的有效元素
//0号元素相当于栈底;size-1位置元素相当于栈顶
private int size=0;
//入栈
public void push(int value){
//把value放在数组末尾,此处没有考虑扩容的操作
array[size]=value;
size++;
}
//出栈
public Integer pop(){
if(size<=0){
//此处可以有两种表示方式
//可以返回非法值,也可以抛出异常
return null;
}
int ret=array[size-1];
size--;
return ret;
}
//取栈顶元素
public Integer peek(){
if(size<=0){
return null;
}
int ret=array[size-1];
return ret;
}
public static void main(String[] args) {
MyStackByArrayList mystack=new MyStackByArrayList();
mystack.push(1);
mystack.push(2);
mystack.push(3);
mystack.push(4);
mystack.push(5);
Integer cur=null;
while((cur=mystack.pop())!=null){
System.out.println(cur);
}
}
}
2.2 基于链表实现栈
用链表头部表示栈顶,链表尾部表示栈底
此处我们写一个带傀儡结点的,在头插头删的过程中更方便
public class TestDemo43 {
//一般表示链表都是用头结点表示链表
//只要知道头结点,就能获取到后面的所有结点 "借代" 用局部表示整体
//链表有八种链表
//1.不带环的 vs 带环的
//2.单向的 vs 双向的
//3.带傀儡节点的 vs 不带傀儡结点的
static class Node{
public int val;
public Node next;
public Node(int val) {
this.val = val;
this.next = null;
}
}
Node head=new Node(-1);
public void push(int value){
//头插
Node newNode=new Node(value);
newNode.next=head.next;
head.next=newNode;
}
//接下来pop方法结束 toDelete这个引用就没有了 此时就没有哪个引用保存toDelete的地址了,
// jvm的垃圾回收机制就会把这个节点判定为垃圾,就可以把这个内存自动释放了(可达性分析)
public Integer pop(){
//头删
Node toDelete=head.next;
if(toDelete==null){
//链表为空.删除失败
return null;
}
head.next=toDelete.next;
return toDelete.val;
}
public Integer peek(){
if(head.next==null){
return null;
}
return head.next.val;
}
}
以上就是我们基于顺序表和链表来实现的栈操作,重点是根据栈后进先出的特点来设计栈哦~