1.用数组实现栈
KEY: 用数组实现 栈 push pop peek的核心逻辑:
初始长度和最大长度两个构造器
1. push前判断栈满,开新栈,两个私有的方法getLen和grow
getLen的判断逻辑是,新长度是旧长度的两倍,
· 如果超过上限就,只取上限
· 如果这样去了以后和旧长度相同,就抛栈满异常
grow获取一个newLen,把旧数组的元素全部转移到新数组,
· 直接从0开始转移,因为栈只能在size一端进出
2. pop前判空,空则抛异常
否则size--, 返回栈顶元素
3. peek和pop类似,但不size--。
package com._28_datastructure._02_stack;
import java.util.EmptyStackException;
/**
* 实现集合类: 栈
* 数组实现
* 只能从下标大的一端,添加和删除
*
* @author zxcsjf
* @since 2022/07/08 11:04
*/
public class MyArrayStack<T> {
private static final int INIT_CAPACITY = 10; // 默认初始化长度
private static final int MAX_CAPACITY = Integer.MAX_VALUE - 8; // 最大长度
private Object[] objs; // 存储Object的数组
private int size; // 当前存储的元素个数,也可作为栈顶指针(指向下一个要存的数组下标)
// KEY: 用数组实现 栈 push pop peek的核心逻辑:
// 初始长度和最大长度两个构造器
// 1. push前判断栈满,开新栈,两个私有的方法getLen和grow
// getLen的判断逻辑是,新长度是旧长度的两倍,
// · 如果超过上限就,只取上限
// · 如果这样去了以后和旧长度相同,就抛栈满异常
// grow获取一个newLen,把旧数组的元素全部转移到新数组,
// · 直接从0开始转移,因为栈只能在size一端进出
// 2. pop前判空,空则抛异常
// 否则size--, 返回栈顶元素
// 3. peek和pop类似,但不size--。
// 默认长度的栈,构造器
public MyArrayStack() {
objs = new Object[INIT_CAPACITY];
}
// 指定长度的栈,构造器
public MyArrayStack(int initCapacity) {
if (initCapacity < 1 || initCapacity > MAX_CAPACITY) {
throw new IllegalArgumentException("栈初始化长度不合法!");
}
objs = new Object[initCapacity];
}
// push
// pop
// peek
/**
* 压栈操作
*
* @param value
* @return 若成功,返回true
* @author zxcsjf
* @since 2022/07/08 20:28:56
*/
public boolean push(T value) {
// 若数组满了,开辟一个新的数组,并且复制过去
if (size == objs.length) {
// 获得一个新的数组长度
int newLen = getLen();
// 根据新的数组长度进行扩容
grow(newLen);
}
// 数组没满,直接压栈,栈顶指针后移
objs[size++] = value;
return true;
}
// 扩容数组,私有方法
private void grow(int newLen) {
// 创建一个新数组
Object[] newObjects = new Object[newLen];
// 把旧数组数据转移到新数组
for (int i = 0; i < objs.length; i++) {
newObjects[i] = objs[i];
}