栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈具有记忆作用,对栈的插入与删除操作中,不需要改变栈底指针。
首先系统或者数据结构栈中数据内容的读取与插入(压入push和 弹出pop)是两回事!压入是增加数据,弹出是删除数据 ,这些操作只能从栈顶即最低地址作为约束的接口界面入手操作 ,但读取栈中的数据是随便的没有接口约束之说。很多人都误解这个理念从而对栈产生困惑。
栈顶指针指向的是下一个要插入的元素的位置。
可以简单地看一下图片(自己画的比较丑),结合下面的数组实现方式代码理解一下栈的原理
数组实现栈数据结构的功能code。
public class ArrayStack<T> {
// 数组实现栈
private Object[] arr;
// 栈顶指针,指向下一个插入元素的位置
private int top;
// 初始化一个大小
private final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
// 当前栈的大小(数组中的元素的个数,可以用栈顶指针来代替size = top),为了分的清楚还是引入这个变量
private int size;
//两种初始化方式:指定初始化大小和不指定初始化大小
public ArrayStack(int initSize) {
if (initSize < 0) {
throw new IllegalArgumentException("stack init size can't less than zero");
}
this.arr = new Object[initSize];
// 栈中存储的数据的个数
this.size = 0;
// 初始化时栈顶指针指向数组0索引位置的
this.top = 0;
}
// 使用无参构造默认数组初始大小16
public ArrayStack() {
this.arr = new Object[DEFAULT_INITIAL_CAPACITY];
this.top = 0;
this.size = 0;
}
/**
* 入栈流程:
* 若TOP≥n时,则给出溢出信息,作出错处理(进栈前首先检查栈是否已满,满则溢出;不满则作②);
* 置TOP=TOP+1(栈指针加1,指向进栈地址);
* S(TOP)=X,结束(X为新进栈的元素);
* @param t
*/
public boolean push(T t) {
if (size >= arr.length) {
throw new IllegalArgumentException("stack overflow exception");
}
// 新加入的元素放到栈顶并且栈顶指针上移动一位
arr[top++] = t;
// 每加入一个新的元素栈大小+1
size++;
// 添加成功返回true
return true;
}
/**
* 出栈流程:
* 若TOP≤0,则给出下溢信息,作出错处理(退栈前先检查是否已为空栈, 空则下溢;不空则作②);
* X=S(TOP),(退栈后的元素赋给X):
* TOP=TOP-1,结束(栈指针减1,指向栈顶)。
* @return
*/
public boolean pop() {
if (top <= 0) {
throw new IllegalArgumentException("stack is empty");
}
// 出栈指针下移
top--;
// 栈大小减一
size--;
// 出栈完成返回true
return true;
}
//查看目前栈顶数据
public T getTop() {
if (top == 0) {
throw new IllegalArgumentException("stack is empty");
}
// 返回栈顶元素(arr[top - 1])
return (T) arr[size - 1];
}
// 查看栈中任意位置上的元素
public T get(int index){
if(index < 0 || index >= size){
throw new IllegalArgumentException("out of bound exception");
}
return (T) arr[index];
}
// 查看栈的大小
public int size(){
// size设置为方法可以避免用户随意修改栈的大小
return size;
}
}
写完代码之后可以简单测试一下功能是否与预期的相符。
class test {
public static void main(String[] args) {
// 指定初始化大小为3
ArrayStack<Integer> arrayStack = new ArrayStack<>(3);
// 入栈
arrayStack.push(10);
arrayStack.push(20);
arrayStack.push(30);
// arrayStack.push(30); // (上溢出)添加第四个元素报出异常:stack overflow exception
System.out.println(arrayStack.size()); // 3
System.out.println(arrayStack.getTop()); // 30
System.out.println(arrayStack.get(0)); // 10
// System.out.println(arrayStack.get(3)); // 下标越界
// 出栈
arrayStack.pop();
System.out.println(arrayStack.size()); // 2
arrayStack.pop();
arrayStack.pop();
// arrayStack.pop(); // 栈中没有元素再进行出栈操作:stack is empty
System.out.println(arrayStack.size()); // 空栈大小为0
}
}
转载:https://blog.csdn.net/qq_39210972/article/details/101471852
查看评论