1. 应用场景
- 程序的调用:程序指令的地址储存在堆栈内,每执行一个程序,就先放入栈中,执行完当前程序就从栈内取出下一个执行。
- 递归调用的处理:除了存程序指令地址,还存参数、区域变量等。
- 表达式转换和求值:如 “中缀 -> 后缀”
- 二叉树的遍历
- 图的深度优先算法(DFS)
2. 特点
- 结构:线性结构
- 栈顶(top) :栈的顶部,出栈入栈的出入口
- 栈底(bottom):栈的底部,最先入栈和最后出栈的位置
- 专有名词:
- 出栈(pop):从 栈顶 取出
- 入栈(push):从 栈顶 放入
- 先进后出 (FILO - First In Last Out) : 先入栈的后出栈。
- 缺点:有长度限制
3. 数据结构(类结构)
(1)成员变量(Field)
- maxSize: int,数组长度,栈可储存的最大数据数量
- array: int[ ],储存栈数据的数组
- top: int,指向栈顶数据
private int maxSize;
private int[] array;
private int top = -1;
(2)初始化 / 构造器(Constructor)
public ArrayStackPractice(int maxSize) {
this.maxSize = maxSize;
this.array = new int[maxSize];
}
(3)方法(Methods)
- 判断栈是否为空
isFull() -> boolean
/**
* 判断栈是否已满
* @return - true 已满, false 未满
*/
public boolean isFull() {
// 若top指向数组末尾,已满
return this.top == this.maxSize - 1;
}
- 判断栈是否已满
isEmpty() ->boolean
/**
* 判断栈是否为空
* @return - true 为空,false 非空
*/
public boolean isEmpty() {
// 若top指向-1位置,为空
return this.top == -1;
}
- 添加数据到栈(入栈)
push(int) -> void
/**
* 入栈
* @param data - 要添加的数据
*/
public void push(int data) {
// 判断是否已满
if (this.top == this.maxSize - 1) {
throw new RuntimeException("is full");
}
// top加1
this.top++;
// 添加数据到数组
this.array[top] = data;
}
- 从栈内取出数据(出栈)
pop() -> int
/**
* 出栈
* @return - 要取出的数据
*/
public int pop() {
// 若数组为空,抛出异常
if (this.top == -1) {
throw new RuntimeException("empty");
}
// 设置临时int变量,储存要出栈的数据
int data = this.array[this.top];
// 从数组内删除数据,并更新top
this.array[this.top] = 0;
top--;
return data;
}
- 获取栈的有效数据数目
getLength() -> int
/**
* 获取栈的有效数据数目
* @return - 返回有效数据数
*/
public int getLength() {
return this.top + 1;
}
4. 完整实现
/**
* 数组实现的栈
*/
public class ArrayStack {
private int maxSize;
private int[] array;
private int top = -1;
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
this.array = new int[maxSize];
}
/**
* 判断栈是否已满
* @return - true 已满, false 未满
*/
public boolean isFull() {
// 若top指向数组末尾,已满
return this.top == this.maxSize - 1;
}
/**
* 判断栈是否为空
* @return - true 为空,false 非空
*/
public boolean isEmpty() {
// 若top指向-1位置,为空
return this.top == -1;
}
/**
* 入栈
* @param data - 要添加的数据
*/
public void push(int data) {
// 判断是否已满
if (this.top == this.maxSize - 1) {
throw new RuntimeException("is full");
}
// top加1
this.top++;
// 添加数据到数组
this.array[top] = data;
}
/**
* 出栈
* @return - 要取出的数据
*/
public int pop() {
// 若数组为空,抛出异常
if (this.top == -1) {
throw new RuntimeException("empty");
}
// 设置临时int变量,储存要出栈的数据
int data = this.array[this.top];
// 从数组内删除数据,并更新top
this.array[this.top] = 0;
top--;
return data;
}
/**
* 获取栈的有效数据数目
* @return - 返回有效数据数
*/
public int getLength() {
return this.top + 1;
}
/**
* 从栈顶开始打印全部数据
*/
public void displayAllDataFromTop() {
// 判断是否为空
if (this.top == -1) {
throw new RuntimeException("empty");
}
// 遍历数组,逐个打印有效数据
for (int i = this.top; i >= 0; i--) {
if (i == this.top) {
System.out.printf("array[%d]: %d (top) \n", i, this.array[i]);
} else if (i == 0) {
System.out.printf("array[%d]: %d (bottom) \n", i, this.array[i]);
} else {
System.out.printf("array[%d]: %d \n", i, this.array[i]);
}
}
}
}