# 介绍
## 特点
栈(Stack)是一种 `后进先出`(英文:LIFO:Last In First Out) 的线性数据结构,并且只能 `从一头` 进出。
栈主要有两个操作:
入栈:将数据放到栈顶
出栈:将栈顶数据弹出栈,栈顶向下移一位
![](https://img.kancloud.cn/fa/a3/faa3d59bac89735ba61a77d9269c3586_520x464.png)
练习题:有 abcde 五个元素依次入栈(过程中可以出栈),以下得到的出栈结果是错误的是?
a. edcba
b. badec
c. eacbd
d. bcdae
答案:C 选项是错误的!根据栈的特点不可能得到 C 这个出栈结果。
练习题:有 abc 三个元素依次入栈(过程中可以出栈),以下得到的出栈结果是错误的是?
a. bac
b. cba
c. abc
d. cab
# 实现方式
栈的实现有两种方式:
- 顺序栈(数组实现)
- 链式栈(链表实现)
## 顺序栈
用 `数组` 来实现一个栈结构。
~~~
class Stack {
construct() {
this._stack = [] // 桶中的数据
}
// 入栈操作
push(data) {
this._stack.push(data)
}
// 出栈操作
pop() {
return this._statck.pop()
}
// 清空栈
clear() {
this._stack = []
}
// 获取栈中元素的数量
count() {
return this._stack.length
}
}
~~~
现实中的面试题:使用 JS 来模拟一个栈。
## 链式栈
用 `链表` 来实现栈的结构。
~~~
// 定义节点类
class Node {
constructor( data ) {
this.data = data // 节点中的数据
this.next = null // 下一个节点
}
}
// 栈
class LinkedListStack {
constructor() {
this.head = null // 栈顶元素
this.length = 0 // 栈中元素的个数
}
// 入栈
push( data ) {
// 1. 创建一个新的节点
let newNode = new Node(data)
// 2. 让这个新节点指向原来的栈顶节点
if(this.head === null) {
// 如果是空节点,那么 head 直接指向这个新节点
this.head = newNode
} else {
// 让新节点指向原栈顶节点
newNode.next = this.head
// 让新节点变成栈顶
this.head = newNode
}
// 3. 栈中元素数量+1
this.length++
}
// 出栈
pop() {
// 1. 先取出栈顶节点中的数据
let data = this.head.data
// 2. 把 head 指针指向下一个元素(删除原栈顶元素)
this.head = this.head.next
// 3. 栈中元素的数量-1
this.length--
// 4. 返回原栈顶元素
return data
}
}
~~~