【数据结构与算法】1.栈

85 阅读1分钟

栈是一种后进先出的结构,符合后进先出规律的场景可以用栈来解决。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
  • 十进制转二进制

image.png

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()