栈作为一个常用的数据结构(如果有不太理解什么是数据结构的请点这里),其使用范围还是非常广泛的。今天我们就一起了解一下“栈”。
简介
栈是线性结构当中一种特殊的线性表,它会限制元素的插入和删除,并且是一个有序的列表。栈存取数据都是在线性表的一端进行的,存取数据的一端称为“栈顶”,另一端则是“栈底”。这种存取方式就造就了栈具有先入后出的特点,也就是第一个存储的数据会在最后一个取出来。举个例子来说栈就像是一个弹夹,栈中的数据就好比是一枚枚的子弹。开枪射出的第一枚子弹都是最后一个压入弹夹的。这样说大家是不是大概都能明白栈是一种什么样的结构?如果还是不太清楚的话请看下图。
通过上面的描述和图片相信大家对栈这个数据结构有了一个大致的概念。学习一个新东西肯定是为了使用,那么它有什么用途呢?别急别急,拿好小板凳让们来了解一下。
应用场景
1、子程序的调用:在跳往子程序前,会先将下个指令的地址存到栈中,直到子程序执行完再将地址取出,以回到原来的程序中。
2、处理递归调用:和子程序调用类似,除了存储下一个指令的地址外,也将参数、区域变量等数据存入栈中。
3、表达式的转换【中缀表达式转后缀表达式】。
4、二叉树的遍历。
5、图形的深度优先(depth-first)搜索法。
以上就是栈比较常见的一些应用场景。在之后的文章中我也会为大家仔细介绍这些场景下是如何运用栈的。
下面重头戏来喽,让我们一起来动手实现一个“栈”!
代码实现
通过数组实现栈:
public class ArrayStack {
// 栈的最大容量
private int maxSize;
// 存放数据(使用数组)
private int[] stack;
// 栈顶指针
private int top = -1;
/**
* 构造方法
*
* @param maxSize 栈的最大容量
*/
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
// 初始化数组
this.stack = new int[this.maxSize];
}
}
判断栈空的方法:
public boolean isEmpty() {
// 当栈顶指针为-1时代表当前栈还没有存入元素
return this.top == -1;
}
判断栈满的方法:
public boolean isFull() {
// 当栈顶的指针等于栈最大容量减一时,代表栈满了(指针指向的是stack的索引,是从0开始的)。
return this.top == this.maxSize - 1;
}
压栈(入栈)的方法:
public void push(int value) {
// 验证是否还可以压入数据
if (this.isFull()) {
System.out.println("栈满了!");
return;
}
// 先移动栈顶指针
this.top++;
// 保存数据
this.stack[this.top] = value;
}
弹栈(出栈)的方法:
public int pop() {
// 验证是否还可以取出数据
if (this.isEmpty()) {
throw new RuntimeException("栈空了!");
}
// 取出栈顶数据
int value = this.stack[this.top];
// 将栈顶指针向下移动
this.top--;
return value;
}
今天的分享就到这了,如果感觉写得不错的记得点赞加关注哟!文章有问题的地方也希望大家可以提出,我会及时更改。