携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第28天,点击查看活动详情
栈的概念
栈是一种后入先出(Last In First Out)的数据结构。
什么是后入先出呢?比方说,有一个小巷子,有很多小车驶进去,最后发现是个断头路,那只能原路返回了,但是因为巷子比较窄,只能倒车出去,然而最先进去的车被后面进去的车卡的死死的,除非后面的车先出去,前面紧跟着的车才出得去。这就是栈结构了。
我们看个图加深一下理解:
可以发现,原本的进入顺序是
1->2->3,但是出去顺序只能由3先出去,然后才是2,最后才是1,即3->2->1,拿捏的明明白白的。
栈的几个名词
栈顶与栈底
由于栈是 后入先出 的数据结构,因此它的顶和底与栈元素的进入顺序是不同的。我们通俗的可以将 最后一个进入 的元素叫做栈顶,将 第一个进入 的元素叫做栈底。
入栈与出栈
我们都知道栈是 后入先出 的,入代表着进入,因此入栈这个操作我们是向栈顶添加元素,使之成为新的栈顶元素,保证它能最先出去。而出栈代表着出,后入先出,所以出栈这个操作是 将栈顶元素弹出。通过入栈和出栈这两个概念的理解,我们可以发现栈的操作都是在 同一端 进行的,即我们 只能在栈顶操作。
分析栈结构
通过以上的几点相信大家对栈有了一定的理解,那么我们都知道 Javascript 中原生是没有提供栈这个数据结构的,所以如果我们想要使用,则需要手动去实现它。那么基于前面理解的几个特性,我们很容易就联想到 使用数组来模拟栈结构。
数组有 pop 和 push 方法,其中 pop 是将数组的最后一个元素 弹出(删除),而 push 是向数组中的尾部 添加 一个新元素,这两个方法是不是很像栈的出栈和入栈操作?
手撕栈
class Stack {
constructor() {
this.stack = [];
}
push(v) {
this.stack.push(v);
}
pop() {
if (this.isEmpty()) return void 0;
return this.stack.pop();
}
top() {
if (this.isEmpty()) return void 0;
return this.stack[this.stack.length - 1];
}
isEmpty() {
return this.stack.length;
}
}
const stack = new Stack();
stack.pop(); // undefined
stack.push(1);
stack.top(); // 1
stack.pop(); // 1
巩固练习题
大家有需要巩固练习的也可以看看几道 LeetCode 上的题目: