目录
一、栈的概念
栈是一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈 顶,另一端称为栈底。栈中的数据元素遵守后进先出(Last In First Out)的原则。
进站操作:栈的插入操作叫做进栈/压栈/入栈,数据进入之后放在栈的顶部。
出栈:栈的删除操作叫做出栈。出数据在栈顶。
根据定义,我们可以观察下图来理解一下什么时后进先出。
由图可以看出,入栈的元素是放在栈顶的,进行出栈操作的时候,栈顶元素先出栈。
二、创建一个栈类
1.使用数组来存放栈的元素
2.使用变量计算元素个数
3.设置栈的默认容量
4.代码
public class MyStack {
//存放元素的数组
public int[] elem;
//栈的元素个数
public int usedSize;
public static final int DEFAULT_CAPACITY = 10;//默认栈的容量
public MyStack() {
this.elem = new int[DEFAULT_CAPACITY];
}
}
三、模拟入栈出栈操作
1.对栈的判满操作
如果栈内元素个数达到数组长度,则栈满。
private boolean isFull() {
return usedSize == elem.length;
}
这里使用的是私有的方法,只在栈的内部使用。
2.对栈的判空操作
栈的元素个数为0时,则栈空。
//判断栈是否为空
private boolean isEmpty() {
return usedSize == 0;
}
这里的方法也是私有的,在栈内部使用的方法我都设为私有的,使用私有方法可以将类的内部复杂逻辑封装起来,使外部调用更加简洁。
3.获取栈的元素个数
定义方法,直接返元素个数即可。
//获取元素个数
public int getSize() {
return usedSize;
}
4.入栈操作(核心操作)
1.首先进行栈的判满操作,栈满则二倍扩容。
2.将元素直接放入数组中,元素个数+1。
//入栈操作
public void push(int val) {
//判满,满了扩容
if(isFull()) {
//2倍扩容
this.elem = Arrays.copyOf(elem,2*elem.length);
}
//元素入栈
elem[usedSize] = val;
//个数加一
usedSize++;
}
5.出栈操作(核心操作)
1.出栈首先进行判空操作,如果栈空,则抛出异常
2.元素开始出栈,拿到栈顶元素,并返回
3.进行出栈操作时,直接将栈的元素个数减一,当元素个数为0时,相当于栈空。
//出栈操作
//出栈且弹出元素
public int pop() {
//先进行栈的判空
if(isEmpty()) {
throw new EmptyStackException("栈为空...");
}
//拿到栈顶元素
int inElement = elem[usedSize-1];
//元素个数减1
usedSize--;
return inElement;
}
6.取出栈顶元素
1.先对栈进行判空操作,栈为空进行出栈操作时直接抛出异常。
2.直接返回栈顶元素,也就是数组最后一个元素。
//取出栈顶元素
public int peek() {
//判空
if(isEmpty()) {
throw new EmptyStackException("栈为空...");
}
return elem[usedSize-1];
}
四、完整代码
自定义异常类
public class EmptyStackException extends RuntimeException{
public EmptyStackException() {
}
public EmptyStackException(String s) {
super(s);
}
}
栈类
import java.util.Arrays;
public class MyStack {
//存放元素的数组
public int[] elem;
//栈的元素个数
public int usedSize;
public static final int DEFAULT_CAPACITY = 10;//默认栈的容量
public MyStack() {
this.elem = new int[DEFAULT_CAPACITY];
}
//判断栈是否满了
private boolean isFull() {
return usedSize == elem.length;
}
//判断栈是否为空
private boolean isEmpty() {
return usedSize == 0;
}
//入栈操作
public void push(int val) {
//判满,满了扩容
if(isFull()) {
//2倍扩容
this.elem = Arrays.copyOf(elem,2*elem.length);
}
//元素入栈
elem[usedSize] = val;
//个数加一
usedSize++;
}
//出栈操作
//出栈且弹出元素
public int pop() {
//先进行栈的判空
if(isEmpty()) {
throw new EmptyStackException("栈为空...");
}
//拿到栈顶元素
int inElement = elem[usedSize-1];
//元素个数减1
usedSize--;
return inElement;
}
//取出栈顶元素
public int peek() {
//判空
if(isEmpty()) {
throw new EmptyStackException("栈为空...");
}
return elem[usedSize-1];
}
//获取元素个数
public int getSize() {
return usedSize;
}
}
五、结语
上面完成了对栈的模拟实现。🙂🙂🙂关于栈的实现就到这里了,有啥问题欢迎在评论区留言。🙂🙂🙂