JavaScript数据结构于算法 --- 栈

本文深入讲解了栈数据结构的基本概念,包括其后进先出(LIFO)的特点,以及在现实生活和计算机科学中的应用,如函数调用栈。文章还详细介绍了如何基于数组实现栈结构,并提供了栈的常用操作示例,如push、pop、peek等。

1.栈的简介

  • 栈是一种受限的线性表,后进先出
  • LIFO(last in first out)表示就是后进入的元素,第一个弹出栈空间
  • 向一个栈插入新元素叫做进栈,入栈,作为栈顶元素
  • 从一个栈删除元素称作出栈或者退栈,他就是删除栈顶元素,使其相邻的元素成为新的栈顶元素。
    在这里插入图片描述

2.生活中类似栈的

  • 自助餐的托盘,最先放上面的最先被客人拿去。
  • 收到的邮件,最后收到的处于邮箱最顶部。

3.栈的应用

  • 函数调用栈
    我们知道函数之间和相互调用:A调用B,B中调用C,C中调用D
    那么在执行的过程中,先将A压入栈,A没有执行完,所以不会弹出栈
    在A执行的过程的中调用了B,会将B再压入到栈,这时候A在栈底,B在栈顶,B也没有执行完
    B调用C,C进栈,C调用D,D进展

所以当前的栈顺序时 栈底 A -> B -> C -> D 栈顶

D执行完,弹出栈,C/B/A依次弹出栈
在这里插入图片描述
所以我们有函数调用栈的称呼,就来自于他们内部的实现机制(通过栈数据结构实现的)

4.栈结构的题型

  • 1.有6个元素6,5,4,3,2,1的顺序进栈(不是一次性进栈),下面哪一个是不合法的出栈序列:
    判断进栈出栈关系,可以边进边出
    A:5 4 3 6 1 2
    5出栈,所以6必定在栈底,4入栈4出栈,3入栈3出栈,6出栈,2入栈,1入栈,1出栈,2出栈 √

    B: 4 5 3 2 1 6
    4出栈,5,6必定在栈底,5出栈,3入栈,3出栈,2入栈,2出栈,1入栈,1出栈,最后6出栈 √

    C:3 4 6 5 2 1
    3出栈,4,5,6,必定在栈底,4出栈,6出栈(出错,这时候5在栈顶,6在栈底) ×

    D: 2 3 4 1 5 6
    2出栈,3,4,5,6在栈底,3出栈,4出栈,1入栈,1出栈,5出栈,6出栈 √

5.栈结构的实现(基于数组实现栈结构)

  • 1.基于数组实现
    包装数组,外层具有栈的特性,内部还是数组

  • 2.基于链表实现(之后补充)

6.栈的常见操作

  • push() 添加一个新元素到栈顶位置
  • pop() 移除栈顶的元素,同时返回被移除的元素
  • peek() 返回栈顶元素,不对栈做任何修改
  • isEmpty() 如果栈中没有元素返回true,否则返回false
  • size() 返回栈中元素个数
  • toString() 将栈中的内容以字符形式返回

7.栈结构的封装

    /**
 * 栈结构的实现
 * 基于数组实现
 */

//1.封装栈的类
function Stack() {
    //栈中的属性
    this.items = [];
    //2.栈的相关操作
    //2.1 入栈
    //给所有实例添加的方法
    // this.push = function(){

    // }

    //添加到原型上(给整个类添加的方法)  效率很明显高很多
    Stack.prototype.push = function(element){
        this.items.push(element);
    }
    //2.2 从栈中去除元素
    Stack.prototype.pop = function(){
        this.items.pop();
    }
    //2.3 查看一下栈顶元素(不改变栈结构)
    Stack.prototype.peek = function(){
        return this.items[this.items.length - 1];
    }
    //2.4 判断栈是否为空
    Stack.prototype.isEmpty = function(){
        return this.items.length == 0;
    }
    //2.5 获取栈中元素的个数
    Stack.prototype.size = function(){
        return this.items.length;
    }
    //2.6 toString方法
    Stack.prototype.toString = function(){
        let resultString = '';
        for(let i= 0; i< this.items.length; i++){
            resultString += this.items[i] + ',';
        }
        return resultString;
    }
}
//栈的使用
var stack = new Stack();
//1.push
stack.push(10);
stack.push(20);
stack.push(30);
stack.push(40);
console.log(stack);
// items: (4) [10, 20, 30, 40]

//2.pop
stack.pop();
console.log(stack);
// items: (3) [10, 20, 30]  40最后入栈,最先出去

//3.peek
stack.peek();
//30  此时栈顶元素是30

//4.isEmpty
stack.isEmpty();
//false

//5.size
stack.size();
//3

//6.toString
stack.toString();
//"10,20,30,"

8.栈结构实现10进制转换为2进制

例如将100转换为2进制
100/2 余 0
50/2 余 0
25/2 余 1
12/2 余 0
6/2 余 0
3/2 余 1
1/2 余 1

这时候1100100就是100的二进制,利用栈将余数一次压入栈底最后将栈输出

function dec2bin(decNumber){
    //1.需要一个栈
    var stack = new Stack();
    // 2.循环操作
    while(decNumber > 0){
        //2.1 获取余数放入栈中
        stack.push(decNumber % 2);
        //2.2 获取整除后的结果作为下一次运算的数组 使用Math.floor 向下取整
        decNumber = Math.floor(decNumber / 2);
    } 
    //3.从栈中取出结果
    var finalString = '';
    while(!stack.isEmpty()){
        finalString += stack.pop();
    }

    return finalString;
}

dec2bin(100); //"1100100"
dec2bin(1000); //"1111101000"
  • 相关学习 codewhy 老师<js数据结构与算法>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值