JavaScript 数据结构与算法(三)栈

数组是一个线性结构,并且可以在数组的任意位置插入和删除元素。
但是有时候,我们为了实现某些功能,必须对这种任意性加以限制。
栈和队列就是比较常见的受限的线性结构。

什么是栈

栈(stack)是一种运算受限的线性表:

  • LIFO(last in first out)表示就是后进入的元素,第一个弹出栈空间。类似于自动餐托盘,最后放上的托盘,往往先把拿出去使用。
  • 其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。
  • 向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;
  • 从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。

如下图所示:

栈的特点:先进后出,后进先出

程序中的栈结构

  • 函数调用栈:A(B(C(D()))):
    即 A 函数中调用 B,B 调用 C,C 调用 D;在 A 执行的过程中会将 A 压入栈,随后 B 执行时 B 也被压入栈,函数 C 和 D 执行时也会被压入栈。所以当前栈的顺序为:A->B->C->D(栈顶);函数 D 执行完之后,会弹出栈被释放,弹出栈的顺序为 D->C->B->A;

  • 递归:
    为什么没有停止条件的递归会造成栈溢出?比如函数 A 为递归函数,不断地调用自己(因为函数还没有执行完,不会把函数弹出栈),不停地把相同的函数 A 压入栈,最后造成栈溢出(Queue Overfloat)。

练习

题目:有 6 个元素 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 (√)

题目所说的按顺序进栈指的不是一次性全部进栈,而是有进有出,进栈顺序为 6 -> 5 -> 4 -> 3 -> 2 -> 1。

解析:

  • A 答案:65 进栈,5 出栈,4 进栈出栈,3 进栈出栈,6 出栈,21 进栈,1 出栈,2 出栈(整体入栈顺序符合 654321)。
  • B 答案:654 进栈,4 出栈,5 出栈,3 进栈出栈,2 进栈出栈,1 进栈出栈,6 出栈(整体的入栈顺序符合 654321)。
  • C 答案:6543 进栈,3 出栈,4 出栈,之后应该 5 出栈而不是 6,所以错误。
  • D 答案:65432 进栈,2 出栈,3 出栈,4 出栈,1 进栈出栈,5 出栈,6 出栈。符合入栈顺序。

栈结构实现

栈常见的操作

  • push() 添加一个新元素到栈顶位置。
  • pop() 移除栈顶的元素,同时返回被移除的元素。
  • peek() 返回栈顶的元素,不对栈做任何修改(该方法不会移除栈顶的元素,仅仅返回它)。
  • isEmpty() 如果栈里没有任何元素就返回 true,否则返回 false
  • size() 返回栈里的元素个数。这个方法和数组的 length 属性类似。
  • toString() 将栈结构的内容以字符串的形式返回。

JavaScript 代码实现栈结构

// 栈结构的封装
class Map {constructor() {this.items = [];}// push(item) 压栈操作,往栈里面添加元素push(item) {this.items.push(item);}// pop() 出栈操作,从栈中取出元素,并返回取出的那个元素pop() {return this.items.pop();}// peek() 查看栈顶元素peek() {return this.items[this.items.length - 1];}// isEmpty() 判断栈是否为空isEmpty() {return this.items.length === 0;}// size() 获取栈中元素个数size() {return this.items.length;}// toString() 返回以字符串形式的栈内元素数据toString() {let result = "";for (let item of this.items) {result += item + " ";}return result;}
}

测试封装的栈结构

// push() 测试
stack.push(1);
stack.push(2);
stack.push(3);
console.log(stack.items); //--> [1, 2, 3]// pop() 测试
console.log(stack.pop()); //--> 3// peek() 测试
console.log(stack.peek()); //--> 2// isEmpty() 测试
console.log(stack.isEmpty()); //--> false// size() 测试
console.log(stack.size()); //--> 2// toString() 测试
console.log(stack.toString()); //--> 1 2

栈结构的简单应用

利用栈结构的特点封装实现十进制转换为二进制的方法。

代码实现

function dec2bin(dec) {// new 一个 Map,保存余数const stack = new Map();// 当不确定循环次数时,使用 while 循环while (dec > 0) {// 除二取余法stack.push(dec % 2); // 获取余数,放入栈中dec = Math.floor(dec / 2); // 除数除以二,向下取整}let binaryString = "";// 不断地从栈中取出元素(0 或 1),并拼接到一起。while (!stack.isEmpty()) {binaryString += stack.pop();}return binaryString;
}

测试

// dec2bin() 测试
console.log(dec2bin(100)); //--> 1100100
console.log(dec2bin(88)); //--> 1011000

03_JavaScript数据结构与算法(三)栈相关推荐

  1. 数据结构与算法之栈入门题目

    数据结构与算法之栈题目 目录 用数组实现大小固定的队列和栈 实现一个特殊的栈,在实现栈的基础功能上,再实现返回栈中最小元素的操作 如果仅用栈结构实现队列结构和如何仅用队列结构实现栈结构 1. 用数组实 ...

  2. 数据结构与算法--简单栈实现及其应用

    栈 栈(Stack)是一种限制插入和删除只能在一个位置上进行的表,改位置是表的末端,叫做栈顶top.栈的基本操作有push (进栈)pop(出栈) 栈又叫做LIFO(后进先出)表,下图展示普通push ...

  3. C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划

    C++数据结构和算法2 栈 双端/队列 冒泡选择插入归并快排 二三分查找 二叉树 二叉搜索树 贪婪 分治 动态规划 博文末尾支持二维码赞赏哦 _ github 章3 Stack栈 和 队列Queue= ...

  4. 数据结构与算法--利用栈实现队列

    利用栈实现队列 上一节中说明了栈的特点 后进先出,我们用数组的方式实现了栈的基本操作api,因此我们对栈的操作是不考虑排序的,每个api的操作基本都是O(1)的世界,因为不考虑顺序,所以找最大,最小值 ...

  5. 数据结构与算法(三) 排序算法(代码示例)

    数据结构与算法三 排序算法 1. 选择排序 2. 插入排序 3. 冒泡排序 4. 归并排序 5. 快速排序 6. 希尔排序 7. 堆排序 总结 1. 选择排序 选择排序的基本原理: 对于未排序的一组记 ...

  6. 新星计划Day7【数据结构与算法】 栈Part1

    新星计划Day7[数据结构与算法] 栈Part1

  7. 数据结构与算法之-----栈的应用(三)

    [ 写在前面的话:本专栏的主要内容:数据结构与算法. 1.对于​​​​​​​初识数据结构的小伙伴们,鉴于后面的数据结构的构建会使用到专栏前面的内容,包括具体数据结构的应用,所使用到的数据结构,也是自己 ...

  8. 数据结构与算法(2)——栈和队列

    前言:题图无关,只是好看,接下来就来复习一下栈和队列的相关知识 前序文章: 数据结构与算法(1)--数组与链表(https://www.jianshu.com/p/7b93b3570875) 栈 什么 ...

  9. 【数据结构与算法】栈与队列

    栈 一.什么是栈? 1.后进者先出,先进者后出,这就是典型的"栈"结构. 2.从栈的操作特性来看,是一种"操作受限"的线性表,只允许在端插入和删除数据. 二.为 ...

最新文章

  1. 第十三届计算机语言学大会,第十三届全国语音学学术会议(PCC 2018) 会议通知第3号...
  2. 向服务器请求数据的五种技术
  3. mysql limit不要1_切记!MySQL中ORDER BY与LIMIT 不要一起用,有大坑
  4. f1 score 代码_腾讯广告算法大赛冠军代码解读:稠密特征工程
  5. Git 合并分支选项 --squash 合并提交历史
  6. [转]HTTP/3 未来可期?
  7. WPS配置工具参数 ksomisc.exe
  8. java log info乱码_跟光磊学Java开发-Java开发常用API的使用
  9. ArcGIS 计算地块容积率
  10. 支付宝 app,网站支付宝登录
  11. openmp 互斥锁 mysql_OpenMP(四)线程同步之互斥锁函数
  12. Lonlife-ACM 1000 - Spoon Devil's 3-D Matrix(最小生成树)——“玲珑杯”acm比赛-试运行赛
  13. Knockout+RequireJS+Sammy搭建简单的SPA脚手架
  14. 11.Python初窥门径(函数名,可迭代对象,迭代器)
  15. 性能测试实战(七):数据驱动
  16. 企查查的批量公司查找
  17. 终于修改了EXE的图标罗
  18. 蒜头君给出若干个整数,询问其中是否有一对数的和等于给定的数。
  19. Mixly 数码管时钟
  20. java.util工具类之Currency类

热门文章

  1. ubuntu硬盘修复
  2. 用ANSYS画矩形_3D建模:用SolidWorks画一个一字螺丝刀
  3. 前端学习 之 JavaScript基础
  4. 定位、相对定位、绝对定位
  5. idea中的marketplace搜不到插件解决方法
  6. 达人评测i5 1340p和i5 12500h差距 酷睿i51340p和i5 12500h选哪个
  7. RabbitMQ基础篇
  8. 太强了,全面解析缓存应用经典问题
  9. vue2.x 标签动态设置背景问题,有透明度
  10. 不得不批,铁道部售票网