• JavaScript 讲述数据结构 - 栈结构


    什么是栈结构 ? 🤔

    栈是一种非常常见的数据结构-并且在程序中的应用非常的广泛

    我们可以用数组来做一个对比


    数组

    数组是一种线性结构,并且可以在数组的任意位置插入和删除数据

    但是有时候我们为了实现某一种功能,必须对这种任意性加以限制

    而队列和栈就是比较常见的受限制的线性结构


    栈结构

    栈结构只能在一端(栈顶【另一端叫做栈底】)

    添加(进栈)和删除(出栈)元素(新元素进栈的过程叫做进栈操作)

    LIFO(last in first out)后进先出(最后进栈的元素将会被第一个弹出栈空间)

    什么是函数调用栈?

    我们知道函数之间的相互调用:A 调用 B,B 调用 C,接着 C 又调用 D,这样的话,在执行过程中,先会将 A 压入栈,此时 A 是没有执行完毕的,所以不会弹出栈

    在 A 执行过程中调用了 B,将 B 压入到栈,这个时候 B 在栈顶,A 在栈底

    如果 B 执行完毕,那么 B 先弹出栈,A 再弹出栈,但是 B 没有执行完,B 又去调用了 C,C 没执行完又去调用了 D

    那么栈顶到栈底现在为:A–>B–>C–>D–>
    D 执行完先弹出栈,接着就是 C–>B–>A

    我们经常会听到递归这个计算机名词,其实递归就是不断的自己调用自己,不会弹出栈,所以会有一个栈溢出的情况


    栈结构练习

    有六个元素 6、5、4、3、2、1 的顺序进栈,那么下面哪一个不是合法的出栈顺序

    A. 5 4 3 6 1 2

    B. 4 5 3 2 1 6

    C. 3 4 6 5 2 1

    D. 2 3 4 1 5 6

    分析 A :

    5 先出栈,那么必然 6 压栈了 --> 5 出去之后,4 进栈再出栈 --> 3 进栈再出栈 --> 然后 6 出栈 --> 接着就是 1 出栈,那么意味着 2 被压栈,所以 1 先出栈 2 再出栈,【正确】

    分析 B :

    4 先出栈,那么意味着 6,5 被压栈 --> 接着 5 出栈 --> 3 进栈,3 出栈 --> 2 进栈,2 出栈 --> 1 进栈,1 出栈 --> 6 出栈 【正确】

    分析 C :

    3 先出栈,那么意味着 6,5,4 被压栈 --> 然后 4 出栈 --> 接着 6 出栈,但是现在 6 被压栈,进栈时后进栈的 5 还没有出去,所以这就造成了错误 【错误】

    分析 D :

    2 先出栈,那么意味着 6,5,4,3 都被压栈 – 3 出栈 --> 4 出栈 --> 然后 1 进栈,1 出栈 --> 5 出栈 --> 6 出栈 【正确】


    堆栈结构

    'use strict'
    
    // 封装栈类
    function Stack() {
      // 栈中的属性
      this.items = []
    
      // 栈的常见操作
      // push(element):添加一个新元素到栈顶位置
      Stack.prototype.push = function (element) {
        this.items.push(element)
      }
      // pop():移除栈顶元素,同时返回被移除元素
      Stack.prototype.pop = function () {
        return this.items.pop()
      }
      // peek():返回栈顶元素,不对栈做任何修改
      Stack.prototype.peek = function () {
        return this.items[this.items.length - 1]
      }
      // isEmpty():如果栈里面没有任何元素就返回true
      Stack.prototype.isEmpty = function () {
        return this.items.length === 0
      }
      // size():返回栈里的元素个数
      Stack.prototype.size = function () {
        return this.items.length
      }
      // toString():将栈结构的内容以字符串的形式返回
      Stack.prototype.toString = function () {
        let resultString = ''
        for (let i = 0; i < this.items.length; i++) {
          resultString += this.items[i] + ' '
        }
        return resultString
      }
    }
    
    // 栈的使用
    let s = new Stack()
    
    // 验证
    s.push(10)
    s.push(9)
    s.push(8)
    s.push(7)
    s.push(6)
    s.push(5)
    console.log(s.items)
    // [ 10, 9, 8, 7, 6, 5 ]
    
    s.pop()
    s.pop()
    console.log(s.items)
    // [ 10, 9, 8, 7 ]
    
    console.log(s.peek())
    // 7
    
    console.log(s.isEmpty())
    // false
    
    console.log(s.size())
    // 4
    
    
    • 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
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65

    计算机基础知识补充 – 基于栈理念理解十进制转二进制

    在计算机中,二进制非常的重要,因为计算机里面所有的内容都是用二进制数字表示的

    把十进制转换为二进制,我们可以将该十进制数字与 2 整除(二进制满二进一),知道结果为 0 为止

    然后翻转取出余数,就是一个二进制数了

    就像这样:

    十进制数:100

    100 / 2 = 50 …0

    50 / 2 = 25 … 0

    25 / 2 = 12 … 1

    12 / 2 = 6 … 0

    6 / 2 = 3 … 0

    3 / 2 = 1 … 1

    1 / 2 = 0 … 1

    二进制:1100100

    这就与栈有些类似了,依次得出元素,接着将最后存储的数字第一个拿出来进行排序,形成一个进栈出栈的原理


    封装进制转换方法

    function DecToBin(decNumber) {
      let stack = new Stack()
      while (decNumber > 0) {
        stack.push(decNumber % 2)
        decNumber = Math.floor(decNumber / 2)
      }
      let binString = ''
      while (!stack.isEmpty()) {
        binString += stack.pop()
      }
      return binString
    }
    
    console.log(DecToBin(100))
    console.log(DecToBin(128))
    console.log(DecToBin(800))
    console.log(DecToBin(10))
    
    // 1100100
    // 10000000
    // 1100100000
    // 1010
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  • 相关阅读:
    AOP介绍
    C#的LINQ select查询、where过滤、group分组、join关联
    AI性能优化之TensorRT(1 tensorrt简介及安装)
    LeetCode 面试题 16.04. 井字游戏
    图神经推荐系统笔记整理
    盘点机PDA搭配蓝牙便携打印机,条码标签打印,超市仓库条码管理,条码标签纸
    pnpm install出现:ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies
    【附源码】计算机毕业设计JAVA疫情下智慧社区系统
    Spring Security 之 JWT介绍
    django+xadmin 在线教育网站(一)
  • 原文地址:https://blog.csdn.net/weixin_63836026/article/details/126412651