栈是一种后进先出的结构,符合后进先出规律的场景可以用栈来解决。JavaScript 没有栈这种数据结构,我们需要用数组来模拟。
const stack = [];
// 入栈
stack.push(1); //[1]
stack.push(2); //[1,2]
// 出栈
const ele1 = stack.pop(); //[1]
const ele2 = stack.pop(); //[]
那么栈可以应用于哪些场景呢?
- 括号匹配,由于越靠后的左括号,对应的右括号越靠前,符合后进先出的规则,我们让左括号入栈,右括号出栈;来判断括号是否有效的闭合,同理,我们也可以用来判断 html 的标签是否有效闭合
() 有效
()) 无效
(()())) 无效
[{)] 无效
/**
* @param {string} s
* @return {boolean}
*/
const isValid = (s) => {
// 如果括号个数为奇数,那么一定不是有效的
if (s.length % 2 === 1) return false;
const stack = []; // 栈结构
// 存储括号的对应关系
const map = new Map();
map.set("(", ")");
map.set("[", "]");
map.set("{", "}");
// 遍历括号字符串
for (let i = 0; i < s.length; i++) {
const c = s[i]; // 拿出每一个括号
if (map.has(c)) {
// 左括号入栈
stack.push(c);
} else {
// 右括号出栈
const t = stack[stack.length - 1]; // 取出栈顶元素(左括号)
// 看一下遍历到的右括号是不是与左括号匹配
if (c === map.get(t)) {
stack.pop(); // 匹配出栈
} else {
return false; // 不匹配则不对应,不是有效的
}
}
}
// 遍历完后栈是否为空
return stack.length === 0;
};
console.log(isValid("()")); // true
console.log(isValid("())")); //false
console.log(isValid("(()()))")); //false
console.log(isValid("[{)]")); //false
- 十进制转二进制
const tenToBin = (num) => {
const stack = [];// 栈中存储的结果需要倒序输出,正好符合先进后出
while (num > 0) {
stack.push(num % 2);// 取余数 入栈
num = Math.floor(num / 2);
}
let res = [];
const stackLen = stack.length; // 记录栈的初始长度
for (let i = 0; i < stackLen; i++) {
res.push(stack.pop());// 出栈
}
return res.join("");
};
console.log(tenToBin(11));//1011
- 函数调用栈
- vue3 响应式系统 为了实现组件嵌套时渲染函数嵌套的问题
// 副作用函数栈
const effectStack = []
// 当前副作用函数执行前入栈
effectStack.push(effectFn)
fn()
// 当前副作用函数执行后出栈
effectStack.pop()