XingYun blog
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具

XingYun

冲!
  • JS基础

    • 图解js原型链
    • JS Event Loop
    • 对象的底层数据结构
    • 让你的JavaScript代码简单又高效
    • 函数参数按值传递
    • 判断数据类型
    • 浮点数精度问题和解决办法
    • 常用方法snippet
    • 实现Promise
    • 防抖和节流
    • 巧用sort排序
  • CSS && HTML

    • CSS也需要性能优化
    • class命名规范
    • em、px、rem、vh、vw 区别
    • CSS揭秘阅读笔记
  • 浏览器

    • 浏览器是如何渲染页面的
    • 重排和重绘
    • BOM浏览器对象模型
    • DOM事件
    • 浏览器存储
  • 数据结构

    • JS实现链表
    • JS实现栈与栈应用
    • JS实现常见排序
    • 哈夫曼编码
    • MD5算法
  • vue原理浅析

    • Vue虚拟dom与Diff算法
    • 前端打包文件的缓存机制
    • vue数组为什么不是响应式
    • v-for为什么不能用index做key
  • 前端工程化

    • 浏览器是如何渲染页面的
    • 前端打包需要gzip压缩吗
    • 前端打包文件的缓存机制
    • webpack loader和plugin
  • 轮子&&组件库

    • 实现水波浪进度球
  • 文字转语音mp3文件
  • 文件上传前后端实现
  • moment.js给定时间获取自然月、周的时间轴
  • 实现文件上传功能
  • 批量下载照片
  • leaflet改变坐标原点
  • 网络

    • 有了MAC地址 为什么还需要IP地址
    • 为什么IP地址老是变
    • 我们为什么需要IPV6
    • TCP与UDP
  • 计算机组成原理

    • ASCII、Unicode、UTF-8和UTF-16
  • VSCode

    • VSCode图片预览插件 Image preview
    • rsync:linux间的高效传输工具
  • 算法图解阅读笔记
  • MD5算法
  • JS实现常见排序
  • 邓俊辉算法与数据结构
  • JS实现队列
  • JS实现树的几种遍历方式
  • 二叉树相关
  • 哈希算法
  • 进制转换与js实现
  • JS实现链表
  • JS实现栈与栈应用
    • 算法与数据结构
    XingYun
    2022-03-07
    目录

    JS实现栈与栈应用

    # 一、栈的基础操作

    top() //查看栈顶元素
    pop() // 出栈
    push(item) // 入栈
    length() // 返回栈的大小
    clear() // 清空或者说重置栈
    isEmpty() // 查看栈是否为空
    
    1
    2
    3
    4
    5
    6

    # 二、用数组来模拟栈

    用数组来实现栈简单方便, 一般想到数组,我们的印象大概是这样的

    我们可以想象把数组头朝下立起来

    它就变成栈

    考虑到不能让外界直接利用数组下标访问或者修改栈,需要做一些私有化处理。

    # 三、代码实现

    const Stack = (function() {
      const _items = Symbol() // 闭包 + 唯一标识symbol封装栈保证唯一性
      return class {
        constructor() {
          this[_items] = []
        }
        // 返回栈顶的元素
        top() {
          return this[_items][this[_items].length - 1]
        }
        // 新增元素
        push(el) {
          this[_items].push(el)
        }
        // 删除栈顶的元素并返回这个值
        pop() {
          return this[_items].pop()
        }
        // 清空栈
        clear() {
          this[_items] = []
        }
        // 栈的大小
        length() {
          return this[_items].length
        }
        // isEmpty
        isEmpty() {
          return this[_items].length === 0
        }
      }
    })()
    
    const stack = new Stack()
    stack.push(1)
    stack.push(2)
    stack.push(3)
    console.log(stack)
    stack[_items].push(4)
    console.log(stack)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40

    这里_items 虽然在内存中存在但不是全局对象(闭包的功劳), 所以无法直接访问。

    代码利用了 闭包 + symbol 做唯一标识封装栈保证栈的私有性。

    # 四、利用栈转换进制

    在 js 中,提供了 Number.prototype.toString 方法将十进制转换成其他进制,其实我们自己也可以使用栈这种数据结构,实现十进制的转换。

    十进制转二进制的过程, 就是除二取余、逆序排列的过程,余数挨个入栈,然后再从栈顶挨个将余数取出,进行拼接,就得到了二进制

    function baseConversionBy2(num) {
      const stack = new Stack()
      let res = ''
    
      while (num > 0) {
        stack.push(num % 2)
        num = Math.floor(num / 2)
      }
      while (!stack.isEmpty()) {
        res += stack.pop()
      }
      return res
    }
    console.log(baseConversionBy2(10)) // 1010
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14

    十进制转其他进制也同理

    # 五、栈判断平衡括号

    平衡括号概念

    "{[()]}" 属于平衡括号
    
    "{([)]}" 不属于平衡括号
    
    "{{[}]}" 不属于平衡括号
    
    "{{([](#))}()}" 属于平衡括号
    
    open = '{[('
    
    close = ')]}'
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12

    open 中包含的左半边符号入栈,如果出栈顺序和 close 包含的右半边符号一样,就可以认为是平衡括号

    代码实现:

    
    function check(str) {
      const stack = new Stack()
      const open = "{[("
      const close = "}])"
      let balanced = true
      let index = 0
      let symbol
      let top
    
      while (index < str.length && balanced) {
        symbol = str[index]
    ​
        if (open.includes(symbol)) {
          stack.push(symbol)
        } else {
          top = stack.pop()
          if (open.indexOf(top) !== close.indexOf(symbol)) {
            balanced = false
          }
        }
        index ++
      }
    ​
      if (balanced && stack.isEmpty()) {
        return true
      }
    ​
      return false
    }
    ​
    console.log(check("{[()]}")) // true
    console.log(check("{([)]}")) // false
    console.log(check("{{[}]}")) // false
    console.log(check("{{([][])}()}")) // true
    
    
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    #算法
    上次更新: 2023/04/05, 09:41:10
    JS实现链表

    ← JS实现链表

    最近更新
    01
    JavaScript-test
    07-20
    02
    二维码的原理
    07-20
    03
    利用ChatGPT优化代码
    07-20
    更多文章>
    Theme by Vdoing | Copyright © 2021-2023 XingYun | MIT License
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式