最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Javascript数据结构详解-栈

    正文概述 掘金(ldld)   2021-01-16   519

    一、概念(Stack)

    栈一种数据呈线性排列的数据结构,不过在这种结构中,我们只能访问最新添加的数 据。栈就像是一摞书,拿到新书时我们会把它放在书堆的最上面,取书时也只能从最上面的新 书开始取。

    二、特点

    • LIFO(Last In First Out),即最后添加的数据最先被取出
    • 线性结构排列

    三、Javascript简单实现

    首先,列出一个栈应该具备的基本方法:

    • push(element(s)):添加一个(或几个)新元素到栈顶。
    • pop():移除栈顶的元素,同时返回被移除的元素。
    • peek():返回栈顶的元素,不对栈做任何的修改(这个方法不会移除栈顶的元素,仅仅是返回它)
    • isEmpty():如果栈里没有任何元素都返回true,否则返回false。
    • clear():移除栈里的所有元素
    • size():返回栈里的元素个数,这个方法和数组的length属性很类似。

    直接上ES6代码:

    class Stack{
      constructor(){
        this.items = [];
      }
      push(item){
        this.items.push(item);
      }
      pop(){
        return this.items.pop();
      }
      peek(){
        return this.items.length ? this.items[this.items.length - 1] : undefined;
      }
      isEmpty(){
        return items.length === 0;
      }
      clear(){
        this.items = [];
      }
      size(){
        return this.items.length;
      }
    }
    

    四、思考和优化

    如果你觉得上述代码就能实现一个Stack类?naive! 来看如下代码:

     let stack = new Stack();
     stack.push(1);
     stack.push(2);
     stack.items;
    

    结果输出 Stack: (2) [1, 2]

    也就是说,我们应该每次只能通过peek、push、pop等方法来操作获取栈的信息。 这么直接stack.items访问很明显是不合理的。所以应该把items属性设置为私有的才行。

    思路如下:

    • 1、将items 从constructor中移除
    • 2、用闭包,保证items在被引用的同时不被回收,即用私有变量取代类中属性

    直接上代码:

    
      let Stack = (function () {
        const items = new WeakMap();
        class Stack {
            constructor () {
                items.set(this, []);
            }
    
           push(item){
              let s = items.get(this);
              s.push(item);
            }
            pop(){
              let s = items.get(this);
              return s.pop();
            }
            peek(){
              let s = items.get(this);
              return s.length ? s[s.length - 1] : undefined;
            }
            isEmpty(){
              let s = items.get(this);
              return s.length === 0;
            }
            clear(){
              let s = items.get(this);
              s = [];
            }
            size(){
              let s = items.get(this);
              return s.length;
            }
        }
        return Stack;
    })();
    

    这样,就可以避免通过实例来访问栈的私有属性了。

    顺便再提一下,为什么要用到WeakMap:

    也即是说,我们把一个数组,放到WeakMap中,不可枚举,遍历不到,这就达到了私有变量的效果了。

    五、栈的实际应用

    1、进制转换

    10进制8转化为2进制数

    function conver(num, radix) {
      let stack = new Stack()
      let binaryString = ''
      let digits = '0123456789ABCDEF'
      while (num > 0) {
        stack.push(num % radix)
        num = parseInt(num / radix)
      }
      while (!stack.isEmpty()) {
        binaryString += digits[stack.pop()]
      }
      console.log(binaryString)
    }
    conver(8, 2) // 输出:1000
    
    

    2~9之间的通用的进制转换

     const convertHex = (num, base) => {
        var stack = new Stack();
        while (num > 0) {
            stack.push(num % base);
            num = Math.floor(num / base);
        }
        let converted = "";
        while (stack.length() > 0) {
            converted += stack.pop();
        }
        return converted;
    }
    
    

    2、判断是否是回文

    const isPalindrome = (str) => {
        var stack = new Stack();
        str += ''; // 转换为字符串
        for (let i = 0, i< str.length; i++) {
            stack.push(str[i]);
        }
        let reverseWord = "";
        while (stack.size() > 0) {
            reverseWord += stack.pop();
        }
        return str === reverseWord;
    }
    
    

    3、有效的括号

    思路如下:

    • 1、碰到左括号,压入栈中
    • 2、碰到右括号,直接将原来栈顶的元素给pop出来。
    • 3、如果最终栈的元素为空,说明压入到栈的左括号都有遇到正确的闭合的右括号,被pop出来了。反之,则说明栈里面没有正确的闭合,或者一开始就先压入右括号。
    const isValid = str => {
          const stack = new Stack();
          for(let i = 0;i<str.length;i++){
              if(str[i] === '(' || str[i] === '[' || str[i] === '{'){
                  stack.push(str[i]);
              }else if((str[i] === ')' || str[i] === ']' || str[i] === '}')
              ){
                  stack.size() && stack.pop();
              }
          }
          return stack.size() === 0;
    
       }
    

    六、结语

    要想在互联网的浩浩人海中卷出优势,必须得学好算法。 要想学好算法,得先了解基本的数据结构。 一点点的进步,今天先学好Stack栈。


    起源地下载网 » Javascript数据结构详解-栈

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元