目录

一. 认识栈结构

1.栈结构

1.1 栈(stack)

1.2 生活中类似于栈的

1.3 栈结构的图解

1.4 程序中的函数调用栈是使用栈实现的呢?

1.5 栈面试题

二. 栈结构实现

1.栈的创建

1.1 创建一个栈的类, 用于封装栈相关的操作

1.2 代码解析:

2.栈的操作

2.1 方式一

2.2 方式二

3.栈的使用

三. 栈结构应用

1.十进制转二进制

1.1 为什么需要十进制转二进制

1.2 如何实现十进制转二进制

1.3 代码来实现十进制转二进制


一. 认识栈结构

  • 我们知道数组是一种线性结构, 并且可以在数组的任意位置插入和删除数据.
  • 但是有时候, 我们为了实现某些功能, 必须对这种任意性加以限制.
  • 而栈和队列就是比较常见的受限的线性结构, 我们先来学习栈结构.

1.栈结构

1.1 栈(stack)

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

1.2 生活中类似于栈的

  • 自助餐的托盘, 最新放上去的, 最先被客人拿走使用.
  • 收到很多的邮件(实体的), 从上往下依次处理这些邮件. (最新到的邮件, 最先处理)
  • 注意: 不允许改变邮件的次序, 比如从最小开始, 或者处于最紧急的邮件, 否则就不再是栈结构了. 而是队列或者优先级队列结构.

1.3 栈结构的图解

1.4 程序中的函数调用栈是使用栈实现的呢?

  •  函数调用栈:函数之间和相互调用——A调用B, B中又调用C, C中又调用D.

那样在执行的过程中, 会先将A压入栈, A没有执行完, 所有不会弹出栈.

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

如果这个时候B可以执行完, 那么B会弹出栈. 但是B有执行完吗? 没有, 它调用了C.

所以C会压栈, 并且在栈顶. 而C调用了D, D会压入到栈顶.

所以当前的栈顺序是: 栈顶A->B->C->D栈顶

D执行完, 弹出栈. C/B/A依次弹出栈.

所以我们有函数调用栈的称呼, 就来自于它们内部的实现机制. (通过栈来实现的)

  • 函数调用栈图解:

1.5 栈面试题

  • 面试题目:

  • 注意:顺序进栈并不是一次性全都进栈,所以可以进n个出m个.

  • 题目答案: C

    • A答案: 65进栈, 5出栈, 4进栈出栈, 3进栈出栈, 6出栈, 21进栈,1出栈, 2出栈
    • B答案: 654进栈, 4出栈, 5出栈, 3进栈出栈, 2进栈出栈, 1进栈出栈, 6出栈
    • D答案: 65432进栈, 2出栈, 3出栈, 4出栈, 1进栈出栈, 5出栈, 6出栈

二. 栈结构实现

  • 基于数组:对数组进行包装,让其外层具有栈的特性(栈中都是数组)
  • 基于链表(JS中并没有自带链表结构)

以下演示均为基于数组实现

1.栈的创建

1.1 创建一个栈的类, 用于封装栈相关的操作

        //1.封装一个栈类function Stack() {//栈中的属性this.items = [] //栈的相关操作}//2.栈的使用var s = new Stack()

1.2 代码解析:

  • 我们创建了一个Stack构造函数, 用户创建栈的类.
  • 在构造函数中, 定义了一个变量, 这个变量可以用于保存当前栈对象中所有的元素.
  • 这个变量是一个数组类型. 我们之后无论是压栈操作还是出栈操作, 都是从数组中添加和删除元素.
  • 栈有一些相关的操作方法, 通常无论是什么语言, 操作都是比较类似的.

2.栈的操作

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

2.1 方式一

方式一相当于给对象实例添加了一个方法,即每个类都有function这个方法。

this.push = function() {}

这里我们为了将属性方法放在一起, 没有使用原型来封装方法。

        // 1.栈类function Stack() {// 栈中的属性var items = []// 栈相关的方法// 1.1压栈操作:将最新的元素放在了数组的末尾, 那么数组末尾的元素就是我们的栈顶元素this.push = function (element) {items.push(element)}// 1.2出栈操作:将栈顶的元素删除, 并且返回this.pop = function () {return items.pop()}// 1.3peek操作:和pop不同, peek仅仅的瞥一眼栈顶的元素, 并不需要将这个元素从栈顶弹出this.peek = function () {return items[items.length - 1]}// 1.4获取栈中元素的个数:因为我们使用的是数组来作为栈的底层实现的, 所以直接获取数组的长度即可this.size = function () {return items.length}// 1.5判断栈中的元素是否为空:判断数组中的元素个数是为0, 为0返回true, 否则返回falsethis.isEmpty = function () {return items.length == 0}}

2.2 方式二

方式二相当于给整个类添加了一个方法,即是共享的,节省内存,效率高——最好用这种方式。

Stack.prototype.push = function() {}

        //1.封装一个栈类function Stack() {//栈中的属性this.items = [] //栈的相关操作//1.1将元素压入栈:要写参数作为压入元素Stack.prototype.push = function(element) {this.items.push(element)}//1.2从栈顶取出元素:返回取出的(最后一个/栈顶)元素Stack.prototype.pop = function() {return this.items.pop()}//1.3查看栈顶元素:不在数组中删除掉查看的栈顶元素Stack.prototype.peek = function() {return this.items[this.items.length-1]}//1.4判断栈是否为空:是0则空;非0则非空Stack.prototype.isEmpty = function() {return this.items.length == 0}//1.5获取栈中元素个数Stack.prototype.size = function() {return this.items.length}//1.6栈结构的内容以字符形式返回:若希望以20 10 12 8 7形式返回——遍历Stack.prototype.toString = function() {var resultString = ''for (var i=0; i < this.items.length; i++){resultString += this.items[i] + ' '}return resultString}//1.7移除栈里的所有元素Stack.prototype.clear = function() {this.items=[]}}//2.栈的使用var s = new Stack()//压栈s.push(20) s.push(10)s.push(100)s.push(77)console.log(s) //输出:[20,10,100,77]//弹栈console.log(s.pop()) //输出:77console.log(s) //输出:[20,10,100]//查看栈顶元素console.log(s.peek()) //输出:100console.log(s) //输出:[20,10,100]//判断是否为空console.log(s.isEmpty()) //输出:false//元素个数console.log(s.size()) //输出:3//以字符串形式输出console.log(s.toString()) //输出:20 10 100//清空数组元素console.log(s.clear()) //输出:undefind

3.栈的使用

使用封装的栈, 模拟刚才的面试题中的A(C是无法使用栈来模拟的, 因为C不正确)

// 模拟面试题
var stack = new Stack()// 情况下代码模拟
stack.push(6)
stack.push(5)
stack.pop()     // 5
stack.push(4)
stack.pop()     // 4
stack.push(3)
stack.pop()     // 3
stack.pop()     // 6
stack.push(2)
stack.push(1)
stack.pop()     // 1
stack.pop()     // 2

三. 栈结构应用

1.十进制转二进制

1.1 为什么需要十进制转二进制

  • 现实生活中,我们主要使用十进制。
  • 但在计算科学中,二进制非常重要,因为计算机里的所有内容都是用二进制数字表示的(0和1)。
  • 没有十进制和二进制相互转化的能力,与计算机交流就很困难。

1.2 如何实现十进制转二进制

  • 要把十进制转化成二进制,我们可以将该十进制数字除二取余,倒记余数。

  • 举个例子,把十进制的数字10转化成二进制的数字,过程大概是这样:

1.3 代码来实现十进制转二进制

        //1.封装一个栈类function Stack() {this.items = [] //1.1将元素压入栈:要写参数作为压入元素Stack.prototype.push = function(element) {this.items.push(element)}//1.2从栈顶取出元素:返回取出的(最后一个/栈顶)元素Stack.prototype.pop = function() {return this.items.pop()}//1.3查看栈顶元素:不在数组中删除掉查看的栈顶元素Stack.prototype.peek = function() {return this.items[this.items.length-1]}//1.4判断栈是否为空:是0则空;非0则非空Stack.prototype.isEmpty = function() {return this.items.length == 0}//1.5获取栈中元素个数Stack.prototype.size = function() {return this.items.length}//1.6栈结构的内容以字符形式返回:若希望以20 10 12 8 7形式返回——遍历Stack.prototype.toString = function() {var resultString = ''for (var i=0; i < this.items.length; i++){resultString += this.items[i] + ' '}return resultString}//1.7移除栈里的所有元素Stack.prototype.clear = function() {this.items=[]}}// 2.封装十进制转二进制的函数function dec2bin(decNumer) {// 1.1定义变量var stack = new Stack()var remainder;// 1.2循环除法:while——不确定循环多少次// decNumer:十进制数。remainder:余数while (decNumer > 0) {//获取余数并且放入栈中remainder = decNumer % 2stack.push(remainder)//获取整除后结果,作为下一次运行的数字decNumer = Math.floor(decNumer / 2) //向下取整}// 13将数据从栈中取出var binayriStrng = ""while (!stack.isEmpty()) {binayriStrng += stack.pop()}return binayriStrng}// 测试函数alert(dec2bin(10))alert(dec2bin(233))alert(dec2bin(1000))

【JS数据结构】线性结构——栈结构相关推荐

  1. c语言构造一个空线性表l,数据结构线性表顺序结构的定义与实现C语言-Go语言中文社区...

    大家好,今天给大家总结了一下数据结构里面的线性表的顺序结构,顺序表表示的是用一组地址连续的存储单元依次存储线性表的数据元素,所以顺序结构的实现一般采用数组的方式来实现,存储空间也采用动态分配的方式.在 ...

  2. 数据结构线性表顺序存储结构和主要算法实现

    (1) 线性表的定义. 零个或多个数据元素的有限序列 序列线性表中有直接后继元素,有且仅有一个直接后继,有且仅有一个直接前驱,数据元素之间的关系是一对一的关系 常用的List操作: Operation ...

  3. C语言数据结构线性表顺序存储结构(插入、删除、获取)

    一.代码 #include<stdio.h> #define MAXSIZE 20 /*存储空间初始分配量*/ #define OK 1 #define ERROR 0//元素数据类型,假 ...

  4. node 获取表单数据 为空_寻offer之JS数据结构与算法 -- 栈

    栈 栈是一个线性结构,在计算机中是一种相当常见的数据结构. 栈与数组对比 我们知道数组是一种线性结构,并且可以在数组的任意位置插入和删除数据.但是有时候,我们为了实现某些功能,必须对这种任意性加以限制 ...

  5. 数据结构 线性存储 -- 栈 讲解

    1.栈的定义 我们有时会听到这句话,  静态定义的内存是在栈中分配的, 动态内存是在堆里面分配的. 例如下面这个简单的函数: int f(int k){ int m = 2 * k;int * p = ...

  6. 数据结构 线性链表栈

    #ifndef _MY_LINKSTACK_H_ #define _MY_LINKSTACK_H_typedef void LinkStack;//创建链表栈 LinkStack* LinkStack ...

  7. 2021-9-下旬 数据结构-线性表- 栈 -java代码实现(复习用)

    import java.util.ArrayList; import java.util.List; //栈的本质就是线性表,因为总在线性表的表尾端进行操作(出栈入栈),其重要特性为FILO先进后出 ...

  8. JS数据结构初识(一)-栈

    一.定义 栈是一种遵从后进先出(LIFO)原则的有序集合.新添加的或待删除的元素都保存在栈的末尾,称作栈顶,另一端就叫栈底.在栈里,新元素都靠近栈顶,旧元素都接近栈底. 栈也被用在编程语言的编译器和内 ...

  9. JS 数据结构之旅 :通过JS实现栈、队列、二叉树、二分搜索树、AVL树、Trie树、并查集树、堆

    JS 数据结构之旅 栈 概念 栈是一个线性结构,在计算机中是一个相当常见的数据结构. 栈的特点是只能在某一端添加或删除数据,遵循先进后出的原则 实现 每种数据结构都可以用很多种方式来实现,其实可以把栈 ...

最新文章

  1. Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs
  2. Java软件架构师所要需的东西
  3. 正则表达式过滤HTML危险脚本
  4. java jackson json_使用Java和Jackson将Json序列化为通用结构而无...
  5. Effective C++ -----条款06:若不想使用编译器自动生成的函数,就该明确拒绝
  6. 我的第一个Python程序(简单的用户名密码登录程序)
  7. 应用安全 - 工具使用 - Nmap
  8. 拼多多算法工程师笔试题之分配巧克力
  9. java学习class5
  10. You need to use a Theme.AppCompat theme (or descendant) with this activity
  11. 美国计算机科学本科申请条件,美国计算机专业申请条件
  12. 强者的成功法则:受益一生的书单
  13. 关于java外文翻译_毕业论文外文翻译-Java和因特网
  14. 内网环境下element-template配置element-admin
  15. win10显示隐藏文件_Win10如何隐藏文件 电脑隐藏文件操作方法
  16. python怎么算列表的平方_总算明了python如何求平方
  17. STM32G030C8T6读写flash
  18. Appium常用操作之《元素定位、swipe滑屏操作》
  19. 1小时1篇文学会python再做个飞机大战游戏
  20. 新浪博客代码(第九十三期)-几种视频播放器的代码

热门文章

  1. 迅捷CAD编辑器哪些功能比较好用
  2. 在迅捷CAD编辑器中怎么将CAD图纸批量转为WMF格式?
  3. 精彩机械动图:人类真是太聪明了
  4. 加强安全防范提高护理质量
  5. Python - 操作txt文件
  6. photoshop 错误:暂存盘已满打不开的解决方法
  7. 【调剂】澳门科技大学空间大数据硕士接收调剂研究生
  8. java类加载和双亲委派模型浅说
  9. win10 MinGW-w64安装教程——著名C/C++编译器GCC的Windows版本
  10. 大赛报名 | 2023“领航杯”国际创新创业大赛项目征集启动